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

时间:2011-05-03 14:14:31

标签: python linux sockets networking tcp

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

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

socket.error: [Errno 98] Address already in use

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

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

更新

根据Mike的回答,我查看了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.

3 个答案:

答案 0 :(得分:37)

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

s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind((ADDR, PORT))

答案 1 :(得分:11)

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

答案 2 :(得分:5)

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