Linux 如何关闭被杀死的程序打开的套接字?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5875177/
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
How to close a socket left open by a killed program?
提问by Mr. Shickadance
I have a Python application which opens a simple TCP socket to communicate with another Python application on a separate host. Sometimes the program will either error or I will directly kill it, and in either case the socket may be left open for some unknown time.
我有一个 Python 应用程序,它打开一个简单的 TCP 套接字以与单独主机上的另一个 Python 应用程序进行通信。有时程序会出错,或者我会直接杀死它,在任何一种情况下,套接字可能会在未知的时间内保持打开状态。
The next time I go to run the program I get this error:
下次我去运行程序时,我收到此错误:
socket.error: [Errno 98] Address already in use
Now the program always tries to use the same port, so it appears as though it is still open. I checked and am quite sure the program isn't running in the background and yet my address is still in use.
现在程序总是尝试使用相同的端口,所以它看起来好像仍然是打开的。我检查并确定该程序没有在后台运行,但我的地址仍在使用中。
SO, how can I manually (or otherwise) close a socket/address so that my program can immediately re-use it?
那么,我如何手动(或以其他方式)关闭套接字/地址,以便我的程序可以立即重新使用它?
Update
更新
Based on Mike's answer I checked out the socket(7)
page and looked at SO_REUSEADDR:
根据迈克的回答,我查看了socket(7)
页面并查看了 SO_REUSEADDR:
SO_REUSEADDR Indicates that the rules used in validating addresses supplied in a bind(2) call should allow reuse of local addresses. For AF_INET sockets this means that a socket may bind, except when there is an active listening socket bound to the address. When the listen‐ ing socket is bound to INADDR_ANY with a specific port then it is not possible to bind to this port for any local address. Argument is an integer boolean flag.
SO_REUSEADDR Indicates that the rules used in validating addresses supplied in a bind(2) call should allow reuse of local addresses. For AF_INET sockets this means that a socket may bind, except when there is an active listening socket bound to the address. When the listen‐ ing socket is bound to INADDR_ANY with a specific port then it is not possible to bind to this port for any local address. Argument is an integer boolean flag.
采纳答案by Mike Pennington
Assume your socket is named s
... you need to set socket.SO_REUSEADDR
on the server's socket before binding to an interface... this will allow you to immediately restart a TCP server...
假设您的套接字已命名s
……您需要socket.SO_REUSEADDR
在绑定到接口之前在服务器的套接字上进行设置……这将允许您立即重新启动 TCP 服务器……
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind((ADDR, PORT))
回答by Jean-Paul Calderone
You might want to try using Twisted for your networking. Mike gave the correct low-level answer, SO_REUSEADDR
, but he didn't mention that this isn't a very good option to set on Windows. This is the sort of thing that Twisted takes care of for you automatically. There are many, many other examples of this kind of boring low-level detail that you have to pay attention to when using the socket module directly but which you can forget about if you use a higher level library like Twisted.
您可能想尝试将 Twisted 用于您的网络。Mike 给出了正确的低级答案,SO_REUSEADDR
但他没有提到在 Windows 上设置这不是一个很好的选项。这是 Twisted 自动为您处理的事情。在直接使用 socket 模块时,您必须注意这种无聊的低级细节,还有许多其他示例,但如果您使用像 Twisted 这样的更高级别的库,则可以忘记这些。
回答by user207421
You are confusing sockets, connections, and ports. Sockets are endpoints of connections, which in turn are 5-tuples {protocol, local-ip, local-port, remote-ip, remote-port}. The killed program's socket has been closed by the OS, and ditto the connection. The only relic of the connection is the peer's socket and the corresponding port at the peer host. So what you should really be asking about is how to reuse the local port.To which the answer is SO_REUSEADDR as per the other answers.
您混淆了套接字、连接和端口。套接字是连接的端点,而后者又是 5 元组 {protocol, local-ip, local-port, remote-ip, remote-port}。被杀死的程序的套接字已被操作系统关闭,连接也是如此。连接的唯一遗物是对等方的套接字和对等方主机上的相应端口。所以你真正应该问的是如何重用本地端口。根据其他答案,答案是 SO_REUSEADDR。