2010-04-11 112 views
1

以下是我正在尝试执行的操作: 当新消息可用时,服务器将消息发送给连接的客户端。另一方面,客户端在连接时尝试使用send()向服务器发送消息,然后使用recv()接收消息,之后客户端调用close()来关闭连接。插座未正确关闭的原因?

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

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

回答

1

如果您在客户端中调用close(),并且数据仍在接收队列中,则会发生这种情况。客户端将发送RST而不是FIN,表示并非所有数据都已成功传送到应用程序。如果连接只是为了客户的利益,那么服务器可能不关心;因为在该套接字上没有进一步的通信,所以服务器应该关闭它。

  • 当A被完成发送的所有数据时,它调用shutdown(sock, SHUT_WR)并继续从套接字读取:

    这可以通过关闭连接,如下所示(其中A为发起关闭的一侧)来避免。

  • 当B看到EOF时(例如recv()返回0),它知道A正在发起关闭。 B根据情况发送任何最终答复或其他最终数据,请致电shutdown(sock, SHUT_WR),然后致电close(sock)
  • 当A看到EOF时,如果它已经关闭写入,它只会调用close(sock)

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

+0

感谢您的回答。这正是我遇到的。你能否详细说明“当B看到EOF时,它知道A正在启动关机”?我应该怎么做我的代码呢? – 2010-04-13 09:22:39

+0

没关系。我在这里找到了我的答案(2.6):http://www.faqs.org/faqs/unix-faq/socket/ – 2010-04-13 09:48:17

+0

如果您调用'recv()'或'read()',这些接口通过返回来指示EOF 0。 – mark4o 2010-04-13 15:02:26