我的 Raspberry Pi 上运行着一个小服务器,它监听特定的端口。然而,每当连接过程中发生异常并终止连接时,似乎对端口的分配并未“解除绑定(bind)”。
这是示例代码:
import socket
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.bind(('', 5005))
s.listen(1)
with s.accept()[0] as c:
raise Exception() # Act as if anything goes wrong
当我第一次运行它并在另一个终端上执行 telnet localhost 5005
时,会建立连接并且服务器会按预期引发异常。
但是,当我尝试第二次运行它时,出现以下错误:
Traceback (most recent call last):
File "testsocketexception.py", line 4, in <module>
s.bind(('', 5005))
OSError: [Errno 98] Address already in use
即使服务器上引发异常,如何确保套接字未绑定(bind)? (顺便说一句,这在 Windows 中似乎不会发生。)
最佳答案
在绑定(bind)套接字之前设置SO_REUSEADDR
套接字选项。
the
SO_REUSEADDR
flag tells the kernel to reuse a local socket inTIME_WAIT
state, without waiting for its natural timeout to expire.
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind(('', 5005))
...
注意:如果上次运行时保留了 TIME_WAIT
套接字(没有 SO_REUSEADDR
选项),即使应用此选项,您也会收到错误。
关于Python套接字编程: "Address already in use" after exception,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36690667/