1

这是我想要做的:当有新消息可用时,服务器向连接的客户端发送消息。另一方面,客户端在连接时尝试使用 send() 向服务器发送消息,然后使用 recv() 接收消息,之后,客户端调用 close() 关闭连接。

有时,在客户端完成后,服务器尝试从客户端接收消息会导致 104 -“对等连接重置”错误。发生这种情况时,Wireshark 显示客户端发送的最后两个段是:
1. 确认收到服务器发送的消息的
ACK 2. RST/ACK
客户端没有发送 FIN。

为什么会发生这种情况,如何在客户端“正确”关闭套接字?

4

1 回答 1

1

如果您调用close()客户端时数据仍在接收队列中,则会发生这种情况。客户端将发送 RST 而不是 FIN,以表明并非所有数据都已成功交付给应用程序。如果连接只是为了客户端的利益,那么服务器可能不在乎;由于该套接字上无法进行进一步的通信,因此服务器应该简单地关闭它。

这可以通过关闭连接来避免,如下所示(其中 A 是启动关闭的一方):

  • 当 A 发送完所有数据后,它调用shutdown(sock, SHUT_WR)并继续从套接字读取。
  • 当 B 看到 EOF(例如recv()返回 0)时,它知道 A 正在启动关闭。B 发送任何最终响应或其他适用的最终数据,调用shutdown(sock, SHUT_WR),然后close(sock)
  • 当 A 看到 EOF 时,如果它已经关闭写入,它只会调用close(sock).

请注意,ECONNRESET 仍然是可能的,例如,如果另一个进程被杀死,那么它仍然必须被处理。在这种情况下,发送任何最终响应是没有意义的,因为对方不会收到它,所以在这种情况下应该关闭套接字。

于 2010-04-12T09:47:45.267 回答