Linux 中的正常关闭服务器套接字
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/9681531/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Graceful Shutdown Server Socket in Linux
提问by benmmurphy
I want to be able to stop listening on a server socket in linux and ensure that all connections that are open from a client's point of view are correctly handled and not abruptly closed (ie: receive ECONNRESET).
我希望能够停止侦听 linux 中的服务器套接字,并确保正确处理从客户端的角度打开的所有连接,而不是突然关闭(即:接收 ECONNRESET)。
ie:
IE:
sock = create_socket();
listen(sock, non_zero_backlog);
graceful_close(sock);
if thought calling close() and handling already accept'd sockets would be enough but there can be connections that are open in the kernel backlog which will be abruptly closed if you call close() on the server socket.
如果认为调用 close() 并处理已经接受的套接字就足够了,但是内核积压中可能存在打开的连接,如果您在服务器套接字上调用 close() 则会突然关闭。
采纳答案by Gil
The only working way to do that (that I have found) is to:
唯一可行的方法(我发现)是:
prevent
accept()
from adding more clientshave a list of the open sockets somewhere and to wait until they are all properly closed which means:
using
shutdown()
to tell the client that you will no longer work on that socketcall
read()
for a while to make sure that all the client has sent in the meantime has been pulledthen using
close()
to free each clientsocket.
THEN, you can safely
close()
the listening socket.
防止
accept()
添加更多客户端在某处有一个打开的套接字列表,并等待它们全部正确关闭,这意味着:
使用
shutdown()
告诉客户端,您将在插座上不再工作调用
read()
一段时间以确保在此期间发送的所有客户端都已被拉取然后使用
close()
释放每个客户端套接字。
然后,您可以安全地
close()
监听套接字。
You can (and should) use a timeout to make sure that idle connections will not last forever.
您可以(并且应该)使用超时来确保空闲连接不会永远持续下去。
回答by msw
You are looking at a limitation of the TCP socket API. You can look at ECONNRESET
as the socket version of EOF
or, you can implement a higher level protocol over TCP which informs the client of an impending disconnection.
您正在查看 TCP 套接字 API 的限制。您可以将其ECONNRESET
视为EOF
或的套接字版本,您可以通过 TCP 实现更高级别的协议,该协议通知客户端即将断开连接。
However, if you attempt the latter alternative, be aware of the intractable Two Armies Problemwhich makes graceful shutdown impossible in the general case; this is part of the motivation for the TCP connection reset mechanism as it stands. Even if you could write graceful_close()
in a way that worked most of the time, you'd probably still have to deal with ECONNRESET
unless the server process can wait forever to receive a graceful_close_ack
from the client.
但是,如果您尝试后一种选择,请注意棘手的两军问题,这使得在一般情况下无法正常关闭;这是 TCP 连接重置机制的部分动机。即使您可以graceful_close()
以大部分时间都可以工作的方式编写,您可能仍然需要处理,ECONNRESET
除非服务器进程可以永远等待graceful_close_ack
从客户端接收 a 。