none
WSARecv return 10014 WSAEFAULT RRS feed

  • Question

  • I have spent more than 24 hours to figure this problem. Please help.
    I am using IOCP for client application, this is the workerthread of the IO completion. It kept returning WSAEFAULT at the WSARecv() function, saying The lpBuffers parameter is not completely contained in a valid part of the user address space. But I still can't figure out the problem.
    Code Snippet

    DWORD WINAPI workerThread(LPVOID lParam)
    {
    DWORD dwBytesTransfered = 0, *lpNumberOfBytesRecvd, *lpFlags = 0;
    void *lpContext = NULL;
    OVERLAPPED *pOverlapped = NULL;
    LPPER_HANDLE_DATA lpHandleData = NULL;
    int nResult;
    WSABUF wsaBuf;
    char buffer[MAX_BUFFER_LEN];
    //memset(&buffer, 0, MAX_BUFFER_LEN);
    //memset(&wsaBuf, 0, sizeof(wsaBuf));

    wsaBuf.len = MAX_BUFFER_LEN;
    wsaBuf.buf = buffer;

    while(1)
    {
    //printf("DEBUG %d\n", GetLastError());
    nResult = GetQueuedCompletionStatus(g_hCompletionPort, &dwBytesTransfered,(LPDWORD)&lpContext, &pOverlapped, 10000);

    if(nResult == FALSE || ((nResult == TRUE) && (dwBytesTransfered == 0)))
    {
    printf("GetQueuedCompletionStatus ERROR : %d\n", GetLastError());
    if(GetLastError() != 0) // application has completed successfully
    continue;
    }

    lpHandleData = (LPPER_HANDLE_DATA) lpContext;

    printf("Bytes transfered : %d\n", dwBytesTransfered);
    switch(lpHandleData->opCode)
    {
    case OP_READ:
    printf("Total bytes received : %d\n", wsaBuf.len);
    printf("Data received :\n%s\n",wsaBuf.buf);
    break;
    case OP_CONNECT: // just connected to the server
    printf("Connected\n");
    lpHandleData->opCode = OP_READ;

    printf("DEBUG %d\n", GetLastError());


    memset(&lpHandleData->ol, 0, sizeof(lpHandleData->ol));

    if(WSARecv(lpHandleData->serverSocket, &wsaBuf, 1, lpNumberOfBytesRecvd, lpFlags, &lpHandleData->ol, NULL) == SOCKET_ERROR)
    if(WSAGetLastError() == WSA_IO_PENDING)
    printf("WSARecv WSA_IO_PENDING\n");
    else
    /***************************ERROR 10014 WSAEFAULT **********************
    printf("WSARecv ERROR : %d\n", WSAGetLastError());
    break;
    }
    }

    return 0;
    }


    Monday, July 2, 2007 4:18 AM

All replies

  • Have you tried moving the buffer into heap instead of on the local stack?

     

    I have experienced the same problem, but when using a debugger and setting a breakpoint on the entry to recv(), it does not fail.  Setting a breakpoint anywhere inside the recv function in WS2_32.dll results in success unless the break point is set imeadiately after the actual call to the transport (3rd call within recv). 

     

    Once the buffer is moved into heap, the problem no longer ocurred.  This suspiciously looks like an attempt to prevent a recv from using a stack based buffer.


    Regards

    Dave

     

    Friday, June 13, 2008 11:50 PM
  • lpFlags==NULL in the example code.  A comment posted at the bottom of http://technet.microsoft.com/en-us/library/ms741688(v=VS.85).aspx talks more about what triggers WSAEFAULT other than bad a WSABUF parameter.

    This line:

     DWORD dwBytesTransfered = 0, *lpNumberOfBytesRecvd, *lpFlags = 0;

    Should be:

     DWORD dwBytesTransfered = 0, *lpNumberOfBytesRecvd, Flags = 0;

    then pass &Flags instead of lpFlags.

    Tuesday, July 24, 2012 8:39 PM