未正确关闭套接字的原因?
这是我正在尝试做的事情: 当有新消息可用时,服务器向连接的客户端发送消息。另一方面,客户端在连接时尝试使用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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
如果您在客户端中调用
close()
并且数据仍在接收队列中,就会发生这种情况。客户端将发送 RST 而不是 FIN,以表明并非所有数据都已成功传递到应用程序。如果连接只是为了客户端的利益,那么服务器可能不会关心;由于该套接字上无法进行进一步的通信,因此服务器应该简单地关闭它。可以通过如下方式关闭连接来避免这种情况(其中 A 是发起关闭的一方):
shutdown(sock, SHUT_WR)
并继续从插座。recv()
返回 0)时,它知道 A 正在启动关闭。 B 发送任何最终响应或其他适用的最终数据,调用 shutdown(sock, SHUT_WR),然后调用 close(sock)。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):
shutdown(sock, SHUT_WR)
and continues to read from socket.recv()
returns 0), it knows A is initiating a shutdown. B sends any final responses or other final data as applicable, callsshutdown(sock, SHUT_WR)
, and thenclose(sock)
.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.