Click here to Skip to main content
15,883,807 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I am new to IOCP and struggling with this for last few weeks. I have pasted some core part of my code below related to IOCP.This may not be executed perfectly as I clipped some part to make it easy to understand. I am struggling while receiving the data.As it comes to wsarecv in worket thread, wsarecv returns WSA_IO_PENDING error code so I call WSAGetOverlappedResult to check operation to be completed. Twist comes here, rather it proceed and call my local function ProcessTelegramData after WSAGetOverlappedResult , same part of code(wsarecv called again) is executed again by another worker thread which try to call ProcessTelegramData and buffer value is invalid in it. I am unable to understand why another thread calling wsarecv again when WSAGetOverlappedResult is called and why buffer value is getting invalidated?

C++
unsigned LicTCPServer::WorkerThread(LPVOID lpParam)
{
    //int nThreadNo = (int)lpParam;
    LicTCPServer* pThis = reinterpret_cast<lictcpserver*>(lpParam);
    void *lpContext = NULL;
    OVERLAPPED       *pOverlapped = NULL;
    CClientContext   *pClientContext = NULL;
    DWORD            dwBytesTransfered = 0;
    int nBytesRecv = 0;
    int nBytesSent = 0;
    DWORD             dwBytes = 0, dwFlags = 0;
    //Worker thread will be around to process requests, until a Shutdown event is not Signaled.
    while (WAIT_OBJECT_0 != WaitForSingleObject(g_hShutdownEvent, 0))
    {
        BOOL bReturn = GetQueuedCompletionStatus(
            g_hIOCompletionPort,
            &dwBytesTransfered,
            (LPDWORD)&lpContext,
            &pOverlapped,
            INFINITE);

        if (NULL == lpContext)
        {
            //We are shutting down
            break;
        }
        //Get the client context
        pClientContext = (CClientContext *)lpContext;
        if ((FALSE == bReturn) /*|| ((TRUE == bReturn) && (0 == dwBytesTransfered))*/)
        {
            //Client connection gone, remove it.
            pThis->RemoveFromClientListAndFreeMemory(pClientContext);
            continue;
        }
        WSABUF *p_wbuf = pClientContext->GetWSABUFPtr();
        OVERLAPPED *p_ol = pClientContext->GetOVERLAPPEDPtr();
        //printf("reached %d\n",pClientContext->GetOpCode());
        printf("Get Queued received\n");
        switch (pClientContext->GetOpCode())
        {
        case OP_READ:
            {
                //Once the data is successfully received, we will print it.
                //pClientContext->SetOpCode(OP_WRITE);
                pClientContext->ResetWSABUF();
                dwFlags = 0;
                //int a = recv(pClientContext->GetSocket(), p_wbuf->buf, p_wbuf->len, 0);
                //Get the data.
                if(WSARecv(pClientContext->GetSocket(), p_wbuf, 1, &dwBytes, &dwFlags, p_ol, NULL) == SOCKET_ERROR)
                {
                    if (WSAGetLastError() != WSA_IO_PENDING)
                    {
                        printf("Error occured at WSARecv()\n");
                        return 0;
                    }
                }
                DWORD byteTr = 0;
                WSAGetOverlappedResult(pClientContext->GetSocket(),p_ol,&byteTr,TRUE,&dwFlags);
                if( byteTr > 0 )
                {
                    //doing some operatin on data received
                    printf("Process tele called\n");
                    g_pLicServFunc->ProcessTelegramData(pClientContext->GetSocket(), p_wbuf->buf, byteTr);
                }
                if ((SOCKET_ERROR == nBytesRecv) && (WSA_IO_PENDING != WSAGetLastError()))
                {
                    //WriteToConsole("\nThread %d: Error occurred while executing WSARecv().", nThreadNo);
                    //Let's not work with this client
                    //TBC
                    //RemoveFromClientListAndFreeMemory(pClientContext);
                }
            }
            break;
        case OP_WRITE:
            char szBuffer[MAX_BUFFER_LEN];
            //Send the message back to the client.
            pClientContext->SetOpCode(OP_READ);

            pClientContext->SetTotalBytes(dwBytesTransfered);
            pClientContext->SetSentBytes(0);
            //p_wbuf->len  = dwBytesTransfered;
            dwFlags = 0;
            DWORD temp;
            //Overlapped send
            printf("reached Going to send\n");
            //send(pClientContext->GetSocket(), p_wbuf->buf,p_wbuf->len, 0); 
            nBytesSent = WSASend(pClientContext->GetSocket(), p_wbuf, 1, 
                &temp, dwFlags, p_ol, NULL);
            if ((SOCKET_ERROR == nBytesSent) && (WSA_IO_PENDING != WSAGetLastError()))
            {
                //WriteToConsole("\nThread %d: Error occurred while executing WSASend().", nThreadNo);
                //Let's not work with this client
                //TBC
                //RemoveFromClientListAndFreeMemory(pClientContext);
            }
            break;
        default:
            printf("reached to default\n");
            //We should never be reaching here, under normal circumstances.
            break;
        } // switch
    } // while
    return 0;
}
Posted
Updated 7-Sep-11 4:19am
v3

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900