Welcome to Dream.In.Code
Getting C++ Help is Easy!

Join 132,221 C++ Programmers for FREE! Get instant access to thousands of C++ experts, tutorials, code snippets, and more! There are 1,010 people online right now. Registration is fast and FREE... Join Now!




IOCompletionPort: GetQueuedCompletionStatus returns listen socket

 
Reply to this topicStart new topic

IOCompletionPort: GetQueuedCompletionStatus returns listen socket

n8leon
post 13 Mar, 2008 - 02:59 PM
Post #1


New D.I.C Head

*
Joined: 13 Mar, 2008
Posts: 1

Greetings,
this is my first attempt at IOCP, so please forgive me if I am lost in space here...

The Problem: It seems to be almost working, but GetQueuedCompletionStatus is returning the listening socket in the Completion Key instead of the accepting socket.

If I don't add the listening socket to the IOCP, then GetQueuedCompletionStatus doesn't come back at all, even after a client connets to my server.

I have been struggling with this most of the week, and have made very little progress. :-(

Is this a common problem? Something obvious?

If not, here is some sample code - can anybody spot the stupid mistake I must be making?
Is there any way I can examine the internals of the IOCP object to see what it is doing, and possibly how I am using it incorrectly?

TIA,
n8


All error checking and lots of over-head stuff removed for clarity...

CODE

// main:
    g_hToTheMainIocp = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 0);

    hWorkerThreadPool = CreateThread(0, 0, WorkerThread, (void *)(&i), 0, &nThreadID);

    g_theMainListenerSocket = ::WSASocket(AF_INET, SOCK_STREAM, IPPROTO_IP, NULL, 0, WSA_FLAG_OVERLAPPED);

    bind(g_theMainListenerSocket, (sockaddr*)&sinInterface, sizeof(sockaddr));

    listen(g_theMainListenerSocket, 5);

    CreateIoCompletionPort((HANDLE)g_theMainListenerSocket, g_hToTheMainIocp, (ULONG_PTR)g_theMainListenerSocket, 0);

    HANDLE hAcceptThread = CreateThread(0, 0, AcceptThread, (void *)g_theMainListenerSocket, 0, &nThreadID);

    // Wait for exit signal


// AcceptThread:
    SOCKET clientSocket = ::WSASocket(AF_INET, SOCK_STREAM, IPPROTO_IP, NULL, 0, WSA_FLAG_OVERLAPPED);

    HANDLE hIocp = CreateIoCompletionPort((HANDLE)clientSocket, g_hToTheMainIocp, (ULONG_PTR)clientSocket, 0);

    OVERLAPPED ol;
    char buf[1024];
    int bufLen = sizeof(buf);
    DWORD dwBytesRecvd = 0;

    memset(&buf, 0, sizeof(buf));
    memset(&ol, 0, sizeof(ol));

    BOOL bAcceptRes = AcceptEx(
        theMainListenerSocket,
        clientSocket,
        buf,
        bufLen - ((sizeof(sockaddr_in) + 16) * 2),
        sizeof(sockaddr_in) + 16,
        sizeof(sockaddr_in) + 16,
        &dwBytesRecvd,
        &ol);

    // This call returns ERROR_IO_PENDING as expected. :)

    Sleep(forever);


// Worker Thread(s):
    DWORD dwBytesXferred = 0;
    OVERLAPPED* pOl = NULL;
    ULONG_PTR cKey = 0;

    BOOL bRes = GetQueuedCompletionStatus(
        g_hToTheMainIocp,
        &dwBytesXferred,
        &cKey,
        &pOl,
        INFINITE);

// THE PROBLEM: When my client connects, this call returns, but ...
// cKey is set to theMainListenerSocket whereas I was expecting/hoping it would be the clientSocket

// Now, these two calls fail with 10057 ("socket not connected")

    int err = setsockopt( clientFd,
        SOL_SOCKET,
        SO_UPDATE_ACCEPT_CONTEXT,
        (char *)&g_theMainListenerSocket,
        sizeof(g_theMainListenerSocket) );

    int nBytesRecvd = WSARecv(clientFd,
        pWsaBuf, 1, &dwBytes, &dwFlags, pOl, NULL);


User is offlineProfile CardPM

Go to the top of the page

Reply to this topicStart new topic
Time is now: 11/21/08 08:54PM

Live C++ Help!

C++ Tutorials

Reference Sheets

C++ Snippets

Bye Bye Ads

Free DIC T-Shirt

T-Shirt Example

Related Sites

Monthly Drawing

Thumb Drive

Partners

Top Contributors

Top 10 Kudos This Month