Winsock recv()无休止地收到10053 WSAECONNABORTED错误

时间:2014-06-21 16:16:23

标签: c++ mfc winsock

我希望我不会错过一个简单的解决方案,但我一直在寻找好几天。

我的MMO客户端/服务器Winsock MFC架构在大多数情况下都运行良好。

在客户端关闭连接的极少数情况下,服务器将收到10053 WSAECONNABORTED错误消息。即使是合法的客户关闭。以下是处理传入消息的服务器代码,为未优化的代码道歉:

//-----------------------------------------------------------------------------
LRESULT CDXDisplay::DefWindowProc(UINT message, WPARAM wParam, LPARAM lParam) 
{

switch (message) //handle the messages
{
case 39245: //Network port number
    {
        switch (lParam) //If so, which one is it?
        {
        case FD_ACCEPT:
    VGlobal::sSocket.AcceptSocket();

            break;

        case FD_CONNECT:

            break;

        case FD_READ:
            VGlobal::sSocket.receiveSocket = wParam;
            VGlobal::sSocket.ReceivePacket();

            break;

        case FD_WRITE:

            break;

        case FD_CLOSE:

            VGlobal::sSocket.CloseClientConnection( wParam );
            break;
        }
    }
    break;

    default:
        if(message == WM_EXITSIZEMOVE || (message == WM_SIZE && (wParam == SIZE_MAXIMIZED /*|| wParam == SIZE_RESTORED*/)))
        {
            OnSizeScreen();     
            MainVant->SetDisplayMode(0);
        }

        return CDialog::DefWindowProc(message, wParam, lParam);
        //return CWnd::DefWindowProc(message, wParam, lParam);
}



return CDialog::DefWindowProc(message, wParam, lParam);

}

程序将收到数据包,触发FD_READ,然后调用ReceivePacket()

//-----------------------------------------------------------------------------
int SocketServer::ReceivePacket( char * tBuffer, int tReceived )
{

ClientInfo::_packetInfo tPacket;

if( tBuffer == NULL )
{

    char buffer[4096];
    memset(buffer, 0, sizeof(buffer));
    int received = recv( receiveSocket, buffer, sizeof(buffer) - 1, 0 );

            //received = -1 and the WSAGetLastError() ID is 10053
    if( received == -1 )
    {
        int tError = WSAGetLastError();

        return 0;
    }

    if( received == 0 )
        return 0;

            //Handle packet data

    _recvData tRData;
    tRData.length = received;
    //tRData.recvBuffer = buffer;
    tRData.recvSocket = receiveSocket;

    CString convStr;
    LPTSTR aStr = tRData.recvBuffer.GetBufferSetLength(received);
    memcpy( (void*)aStr, buffer, received );

    recvDataList.push_back( tRData );


}


return 1;
}

我只是忽略数据包,等待下一个窗口消息。但是,当我这样做时,DefWindowProc()会不断地一遍又一遍地收到10053错误。

我会假设在MSDN上阅读recv()函数示例以及我在网上找到的其他示例,我需要做的就是"忽略"消息并继续前进,但事实并非如此。然后我假设我的客户端ping超时代码将处理客户端预错误的任何剩余数据,然后在完成后删除客户端信息。

如果我需要一个简单的解决方案来处理这个错误,我非常抱歉,但我似乎无法找到它。

更新1:

在进行进一步测试时,似乎在收到进入DefWindowProc()的不间断套接字消息之前,然后进入recv()函数,我从10053 WSAECONNABORTED获得recv()结果{ {1}}结果,我的服务器的send()功能也首先触发10053 WSAECONNABORTED。这些显然在某种程度上有关,但我仍然感到困惑,如何。

所以最有可能发生的事情是,当客户端关闭时,它没有时间及时将其断开连接消息发送到服务器,因此服务器仍然将数据包数据存储在{{1}中}}命令用于客户端套接字并填写它,直到它最终达到send()函数上的10053错误。

在此之后,我不确定幕后会发生什么。但是,send()函数遇到send()错误后,WSAECONNABORTED会收到无尽的窗口消息,并返回recv()

现在我在这里做了完整的猜测...但我必须假设WSAECONNABORTED函数仍然有一个完整的数据缓冲区等待发送到已经关闭的客户端,并且网络只是不断发送数据到不存在的客户端,然后在send()函数中发回错误?所以我应该以某种方式删除recv()缓冲区中的数据以便清除它,然后服务器可以正常继续吗?

2 个答案:

答案 0 :(得分:0)

根据Microsoft Support:在运行Microsoft Windows Server 2003的计算机上,运行使用Winsock连接的网络程序。当程序调用recv Winsock函数时,您会收到此错误代码

http://support.microsoft.com/kb/925513

答案 1 :(得分:0)

好的,我相信我现在明白了。在我看来,我假设创建一个套接字就像内存分配,如果你在客户端分配内存,你必须在客户端处理它,但网络套接字连接可以作为双向街道处理。我不明白,如果我在客户端上创建套接字连接,我可以使用closesocket()在服务器上关闭它。我以为我必须再次在客户端上处理它,或者让套接字自行解决,直到它意识到连接已经消失,它将终止自己的行为。

所以我希望答案就是在服务器端的客户端套接字上调用closesocket()

所以你的答案是关于调用closesocket()的正确答案,我只是没有将它包裹在我的头上,我可以关闭服务器端的客户端套接字,因为它“技术上”不在客户端或服务器上所有这些都可以在两个程序中死亡。