我创建了一个Win32服务器 - 客户端应用程序,其中许多客户端连接到单个服务器,发送查询和recv
响应。
它在许多安装中都能正常工作,但其他一些连接已关闭。客户端和服务器都报告远程主机已关闭连接。创建连接后的套接字操作顺序如下:
Client: sends query Q1 (by calling send)
Server: recvs query Q1 and sends R1
Client: recvs R1
Client: sends query Q2
Server: recvs query Q2 and sends R2
Client: recvs R2
and so on
在某些网络中,经过一段时间后,例如1小时或10分钟,
Client: Sends Q(n) successfully
Server: recvs SOCKET_ERROR and my code exits thread.
//unexpected
WSAGetLastError() at server returns 10054: An existing connection was forcibly closed by the remote host.
Client: recvs SOCKET_ERROR.
WSAGetLastError() at client also returns 10054
在服务器中,每个客户端都有一个线程。在响应之前,服务器的延迟可以忽略不计。
为什么服务器端的函数recv()
返回SOCKET_ERROR?谁关闭了插座?
编辑:我更新了问题并将WSAGetLastErrorCode()返回值。
为什么-1?这个问题出了什么问题?
答案 0 :(得分:0)
如文件中所述
https://msdn.microsoft.com/en-us/library/windows/desktop/ms740668(v=vs.85).aspx
10054错误
通过对等方重置连接。
远程主机强行关闭现有连接。如果远程主机上的对等应用程序突然停止,主机重新启动,主机或远程网络接口被禁用,或者远程主机使用硬关闭,则通常会产生这种情况(有关远程主机上SO_LINGER选项的更多信息,请参阅setsockopt)插座)。如果由于保持活动活动在一个或多个操作正在进行时检测到故障而导致连接中断,则也可能导致此错误。正在进行的操作因WSAENETRESET而失败。后续操作因WSAECONNRESET而失败。
当您收到此错误时,您可能正在退出程序,因此检查该错误并执行逻辑以从客户端列表或您可能拥有的其他结构中删除客户端并完成其主题,但您不必需要关闭插座。
这是recv()返回值文档
返回值
如果没有错误发生,recv返回接收的字节数,buf参数指向的缓冲区将包含接收到的数据。如果已正常关闭连接,则返回值为零。 否则,返回值SOCKET_ERROR,并且可以通过调用WSAGetLastError来检索特定的错误代码。