没有正确关闭套接字的原因?

时间:2010-04-11 14:19:15

标签: sockets reset

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

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

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

1 个答案:

答案 0 :(得分: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仍然可行,例如,如果其他进程被终止,则必须仍然处理它。在这种情况下,发送任何最终响应是没有意义的,因为另一方将不会收到它,因此在这种情况下应该关闭套接字。