Winsock recv() 无休止地收到 10053 WSAECONNABORTED 错误
Posted
技术标签:
【中文标题】Winsock recv() 无休止地收到 10053 WSAECONNABORTED 错误【英文标题】:Winsock recv() endlessly receives 10053 WSAECONNABORTED error 【发布时间】:2014-06-21 16:16:23 【问题描述】:我希望我不会错过一个简单的解决方案,但我已经找了好几天了。
我的 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()
函数之前,我从recv()
结果中得到不间断的10053 WSAECONNABORTED
结果,我的服务器的send()
函数也会首先触发 10053 WSAECONNABORTED
。这些显然在某种程度上是相关的,但我仍然感到困惑。
那么最有可能发生的情况是,当客户端关闭时,它没有时间及时将其断开连接消息发送到服务器,因此服务器仍然在send()
命令中存储数据包数据客户端的套接字并填充它,直到它最终在send()
函数上遇到10053
错误。
我不确定在此之后幕后发生了什么。但是一旦send()
函数遇到WSAECONNABORTED
错误,recv()
就会得到无穷无尽的窗口消息,同时返回WSAECONNABORTED
。
现在我在这里完全猜测......但我必须假设send()
函数仍然有一个完整的数据缓冲区等待发送到已经关闭的客户端,并且网络只是不断地将数据发送到一个不存在的客户端,然后将错误发送回recv()
函数?那么我是否应该以某种方式删除send()
缓冲区中的数据,以便将其清除,然后服务器可以正常运行?
【问题讨论】:
39245
是怎么回事?你的键盘没有配备字母吗?
对不起,39245 只是正在使用的端口号,当收到一个数据包时,它就是它来自的端口。
我认为您收到WSAECONNABORTED
时需要关闭套接字。
您是指关闭调用send()
的服务器套接字吗?如果是这样,连接到服务器的所有其他客户端会发生什么情况?如果我关闭服务器套接字然后再次打开它,是否会重置每个人与服务器的连接?
【参考方案1】:
根据Microsoft Support:在运行Microsoft Windows Server 2003 的计算机上,您运行使用Winsock 连接的网络程序。当程序调用recv Winsock函数时,你会收到这个错误码
http://support.microsoft.com/kb/925513
【讨论】:
我理解我收到错误的原因,我只是想让服务器不会无限循环通过我的DefWindowProc()
无限循环并出现 10053 错误。此错误也发生在许多不同的 Window 操作系统上,主要是当客户端和服务器仅在 Windows 7 上运行时。我试图理解为什么 DefWindowProc()
不断地一遍又一遍地处理相同的 Winsock 错误消息。【参考方案2】:
好的,我相信我现在明白了。在我看来,我假设创建套接字就像内存分配一样,如果您在客户端分配内存,则必须在客户端处理它,但网络套接字连接可以作为 2 路处理。我不明白如果我在客户端上创建了一个套接字连接,我可以使用closesocket()
在服务器上关闭它。我想我必须在客户端再次处理它,或者让套接字自己工作,直到它意识到连接已经消失,它会终止自己的操作。
所以我希望得到的答案就是在服务器端的客户端套接字上调用closesocket()
。
所以关于调用closesocket()
,你的回答是正确的,我只是没有把它缠在我的头上,我可以在服务器端关闭客户端的套接字,因为它“技术上”根本不在客户端或服务器上,而且在这两个程序中都可能是死亡。
【讨论】:
以上是关于Winsock recv() 无休止地收到 10053 WSAECONNABORTED 错误的主要内容,如果未能解决你的问题,请参考以下文章