none
WSARecv在64位编译下运行10014错误 RRS feed

  • 问题

  • 在vs2010中使用64位编译,WSARECV在64位下执行返回-1,错误号为10014.在MSDN中查阅该错误应该是lpBuffers的指针非法。但我尝试了字节对齐、将WSABUF结构直接临时new,等多种方式,还是无法解决该问题。

    socket的连接没有问题,使用该Socket用recv阻塞方式是可以接收数据的。这段代码在32位编译运行是正常的

    typedef struct PER_HANDLE_DATA
    {
        PER_HANDLE_DATA()
        {
            ZeroMemory(this,sizeof(PER_HANDLE_DATA));
        }
        // ID
        UINT            uID;
        // SOCKET
        SOCKET            dwSockID;    
        int                sPort;
        sockaddr_in        addr;
        // 连接状态回调函数指针
        pfnConnectStatus pCBStatus;
        // For TCP Sever
        pfnConnectStatus pCBStatusSvr;
        // 接收数据回调函数指针
        pfnRcvData         pCBRcvData;    
        // 用户上下文
        LPVOID            pPara;
        // 同步接收和发送及删除SOCKET
    //    HANDLE            hEvt;    
        BOOL            bRemove;
        //Modify By ZGH 2015.11.24 Not Use hEvt
        BOOL            bConfirmRm;
        // 2.1.0.1
        // 内部上下文
        LPVOID            pContext2;
        // 3.0.0.1 For TCP
        pfnTCP_RcvData    pCBRcvData_TCP;
        // UserData
        LPVOID            pUserData;

    }PerHandleData,*LPPerHandleData;

    //IO操作数据
    typedef struct PER_IO_OPERATION_DATA
    {
        PER_IO_OPERATION_DATA()
        {
            ZeroMemory(this,sizeof(PER_IO_OPERATION_DATA));
        }
        //重叠结构
        OVERLAPPED OverLapped;        
        //数据缓冲区
        WSABUF    wsaBuff;
        
        int        nReserved;
        char    cBuff[BUFFER_SIZE];    
        SOCKET    dwSockID;
        
        //操作类型表示 1=发送; 2=接收;
        char    cType;    
        BOOL    bDelete;
        DWORD    dwTick;
        HANDLE    pFileHandle;
    }PerIOData,*LPPerIOData;

            sClt = ::WSAAccept(pPerHdlData->dwSockID,(struct sockaddr*)&addr,&nLen,NULL,0);
            if (INVALID_SOCKET == sClt)
            {            
                continue;
            }       
            //
            pPerHdlDataClt = new PER_HANDLE_DATA;
            if (pPerHdlDataClt)
            {        
                *pPerHdlDataClt = *pPerHdlData;
                pPerHdlDataClt->dwSockID = sClt;
                memcpy(&pPerHdlDataClt->addr,&addr,sizeof(sockaddr_in));

                LPPerIOData     pIOData = new PER_IO_OPERATION_DATA;
                if (pIOData)
                {    
                    pIOData->cType = 2;
                    pIOData->wsaBuff.len = BUFFER_SIZE;
                    pIOData->wsaBuff.buf = pIOData->cBuff;
                    pIOData->dwSockID = sClt;
                    
                    pUserData        = new UserData;
                    if (pUserData)
                    {                
                        pUserData->uID  = pPerHdlData->uID;
                        pUserData->pHdl = pPerHdlDataClt;
                        pUserData->pIO  = pIOData;
                        pPerHdlDataClt->pUserData = pUserData;
                        if (pPerHdlDataClt->pCBRcvData_TCP)
                        {
                            pUserData->nPackHead = 1;
                        }

                        HANDLE hT = CreateIoCompletionPort((HANDLE)pIOData->dwSockID,pThis->m_pNet.m_hIoCP,(ULONG_PTR)pPerHdlDataClt,0);
                        if(!hT)
                        {
                           //delete &close
                        }
                        else
                        {
                            if(::WSARecv(pIOData->dwSockID,&pIOData->wsaBuff,1,&dwRecv,&dwFlag,&pIOData->OverLapped,NULL) == SOCKET_ERROR)
                            {
                                int Errornum = ::WSAGetLastError();
                                if(Errornum == ERROR_IO_PENDING)
                                {
                                    pThis->m_pNet.InsertUserData(pUserData);
                                }
                                else
                                {
                                    LOG("WSARecv Error %d",Errornum); 
                                }                            
                            }
                            else
                            {
                                pThis->m_pNet.InsertUserData(pUserData);
                            }

                      }

                 }

            }

    }


    • 已编辑 Devilzhao 2016年6月2日 2:02 代码重复了
    2016年6月2日 1:50

全部回复

  • MSDN上面知道,这个错误代表这个地址空间不是合法的在用户空间。

    “The lpBuffers parameter is not completely contained in a valid part of the user address space”.

    是因为你有个buffer溢出在你的代码中,每次你循环读取数据,你告诉recv函数去读取数据在buffer的新位置,但是你没有告诉还有多少字节数据在buffer 此位置的后面,所以这个loop将会溢出,最后访问地址就会超出用户空间,所以要告诉有多少字节需要读,这边有个相关的文档,你可以看一下.

    http://stackoverflow.com/questions/14123184/winsock2-error-10014-on-split-tcp-stream

    https://social.msdn.microsoft.com/Forums/windowsdesktop/en-US/0fe72216-f1ad-4b15-aea1-3d75604cebdc/wsarecv-return-10014-wsaefault?forum=wsk

    Note:
    This response contains a reference to a third party World Wide Web site.
    Microsoft is providing this information as a convenience to you. Microsoft does
    not control these sites and has not tested any software or information found on
    these sites; Therefore, Microsoft cannot make any representations regarding the
    quality, safety, or suitability of any software or information found there.


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place. Click HERE to participate the survey.

    2016年6月2日 6:52
    版主
  • 这个WSARecv在Accept之后此时都是新的socket链接,new的新的buff,还没有进行过一次接收,应该不存在循环读取数据的问题。而且我测试的时候客户端只做Connect并不发送数据。。。。而且这段代码在32位编译时是可以正常获取数据的。上面的链接描述的错误跟这段代码的应该不是同一个问题。

    2016年6月2日 10:40
  • 还没有链接成功吗? 程序就出现这个错误吗?三次握手都是没有成功吗? 如果可能,你能提供一个小的demo给我们,我们做一下测试,测试是不是一个API的bug.



    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place. Click HERE to participate the survey.


    2016年6月3日 6:33
    版主
  • 链接已经成功,新的socket加入到完成端口成功,Wsarecv出错。如何发demo给到您。另外demo需要源码还是只是个exe?
    2016年6月3日 10:12
  • 链接已经成功,新的socket加入到完成端口成功,Wsarecv出错。如何发demo给到您。另外demo需要源码还是只是个exe?

    链接已经成功,还没有传输数据,WSARecv函数就出错了? 你可以把源码放到 onedrive。https://onedrive.live.com/,最好能把服务器端和客户端都能给我,这样方便很快重新你的问题。


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place. Click HERE to participate the survey.

    2016年6月6日 8:15
    版主