未正确关闭套接字的原因?

发布于 2024-08-28 02:29:31 字数 288 浏览 4 评论 0原文

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

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

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

Here is what I am trying to do:
The server sends message to connected clients when new messages are available. The client, on the other hand, when connected, tries to send a message to the server using send() and then receive message using recv(), right after that, the client calls close() to close the connection.

Sometimes, after the client finishes, the server tries to receive message from client will result in a 104 - "connection reset by peer" error. When this happens, Wireshark reveals that the last two segments sent by the client is:
1. an ACK acknowledging the receipt of the message sent by the server
2. a RST/ACK
No FIN is sent by the client.

Why is this happening and how can I close the socket "properly" at the client?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

∞梦里开花 2024-09-04 02:29:31

如果您在客户端中调用 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 仍然是可能的,例如,如果其他进程被终止,则仍然必须对其进行处理。在这种情况下,发送任何最终响应是没有意义的,因为另一方不会收到它,因此在这种情况下应该关闭套接字。

This will occur if you call close() in the client with data still in the receive queue. The client will send RST instead of FIN, as an indication that not all data was successfully delivered to the application. If the connection was only for the benefit of the client then probably the server does not care; since no further communication is possible on that socket the server should simply close it.

This can be avoided by shutting down the connection as follows (where A is the side initiating the shutdown):

  • When A is finished sending all data, it calls shutdown(sock, SHUT_WR) and continues to read from socket.
  • When B sees EOF (e.g. recv() returns 0), it knows A is initiating a shutdown. B sends any final responses or other final data as applicable, calls shutdown(sock, SHUT_WR), and then close(sock).
  • When A sees EOF, if it has already shut down writes it just calls close(sock).

Note that ECONNRESET is still possible, if for example the other process is killed, so it must still be handled. In this case there is no point in sending any final response since the other side will not receive it, so the socket should just be closed in that case.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文