如何关闭被杀死程序打开的套接字?

Mr.*_*nce 38 python sockets linux networking tcp

我有一个Python应用程序,它打开一个简单的TCP套接字,与另一个主机上的另一个Python应用程序通信.有时程序会出错或者我会直接杀死它,在任何一种情况下,套接字都可能会在未知时间内保持打开状态.

下次我运行程序时出现此错误:

socket.error: [Errno 98] Address already in use
Run Code Online (Sandbox Code Playgroud)

现在程序总是尝试使用相同的端口,因此它看起来好像仍处于打开状态.我查了一下,我很确定该程序没有在后台运行,但我的地址仍在使用中.

那么,我如何手动(或以其他方式)关闭套接字/地址,以便我的程序可以立即重新使用它?

更新

根据迈克的回答,我查看了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.
Run Code Online (Sandbox Code Playgroud)

Mik*_*ton 37

假设您的套接字已命名s...您需要socket.SO_REUSEADDR在绑定到接口之前设置服务器的套接字...这将允许您立即重新启动TCP服务器...

s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind((ADDR, PORT))
Run Code Online (Sandbox Code Playgroud)


Jea*_*one 11

您可能想尝试使用Twisted进行网络连接.Mike给出了正确的低级答案,SO_REUSEADDR但他没有提到这不是一个在Windows上设置的好选择.这是Twisted自动为您处理的事情.在使用套接字模块时,您必须注意这种无聊的低级细节的许多其他示例,但如果您使用更高级别的库(如Twisted),则可以忘记这些细节.

  • 在Windows上,REUSEADDR允许进程从另一个**仍在运行**进程中接管侦听端口. (6认同)
  • 好吧,这是从 unix.stackexchange.com 迁移的,所以 Windows 可能不是一个大问题。无论如何,好点。+1 (3认同)
  • "这不是一个在Windows上设置的好选择".为什么不? (2认同)

use*_*421 5

您正在混淆套接字,连接和端口.套接字是连接的端点,而后者又是5元组{protocol,local-ip,local-port,remote-ip,remote-port}.被杀死程序的套接字已被操作系统关闭,并且同样是连接.连接的唯一遗留是对等的套接字和对等主机上的相应端口.所以你真正要问的是如何重用本地端口.根据其他答案,答案是SO_REUSEADDR.