IOCompletionPort: GetQueuedCompletionStatus returns listen socket

Discussion in 'C' started by n8leon, Mar 13, 2008.

  1. n8leon

    n8leon New Member

    Joined:
    Mar 13, 2008
    Messages:
    1
    Likes Received:
    0
    Trophy Points:
    0
    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);
    
    
     

Share This Page

  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice