Linux中的平滑closures服务器套接字

我希望能够停止在Linux服务器套接字上侦听,并确保从客户端的angular度打开所有连接正确处理,而不是突然closures(即:接收ECONNRESET)。

即:

sock = create_socket(); listen(sock, non_zero_backlog); graceful_close(sock); 

如果认为调用close()并处理已经accept'd的套接字就足够了,但是可以在内核backlog中打开连接,如果在服务器套接字上调用close(),将会突然closures连接。

唯一的工作方式(我发现)是:

  1. 阻止accept()添加更多的客户端

  2. 有一个开放的插座列表,并等待,直到他们都正确关闭这意味着:

    • 使用shutdown()告诉客户端你将不再使用该套接字

    • 调用read()一段时间,以确保所有的客户端已发送同时被拉

    • 然后使用close()释放每个客户端套接字。

  3. 那么,你可以安全地close()侦听套接字。

您可以(也应该)使用超时来确保闲置连接不会永远持续。

您正在查看TCP套接字API的限制。 您可以将ECONNRESET看作EOF的套接字版本,或者可以通过TCP实现更高级别的协议,以通知客户端即将断开连接。

但是,如果你尝试后一种方法,那么在一般情况下,要注意不可能正常关机的棘手的两军问题 。 这是TCP连接重置机制的动机之一。 即使你可以用大多数时候写的方式来编写graceful_close() ,你可能仍然需要处理ECONNRESET除非服务器进程可以永远等待从客户端接收到一个graceful_close_ack