我有一个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.
答案 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。