s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((HOST, PORT))
s.listen(1)
any_connection = False
while True:
try:
conn, addr = s.accept()
data = conn.recv(1024)
any_connection = True
# keep looking
if not data: continue
pid = os.fork()
if pid == 0:
server_process(data, conn)
except KeyboardInterrupt:
break
if any_connection:
print("Closing connection")
conn.close()
我在用Python编写的无限运行的TCP服务器上捕获KeyboardInterrupt
信号。但是,即使我知道它正在关闭连接,因为它打印Closing Connection
,当我尝试重新运行服务器时,我得到:
OSError: [Errno 48] Address already in use
我不知道发生了什么,因为我肯定知道我正在呼叫conn.close()
。
运行killall python3
无法解决问题,除非我等待很长时间或更改端口,否则我会继续收到错误消息。此外,我试图grep所有python3
进程,但我什么都没得到。
我正在运行OS X Yosemite。
答案 0 :(得分:16)
根据docs出现错误OSError: [Errno 48] Address already in use
,因为
您之前执行的脚本已使套接字处于TIME_WAIT状态,并且无法立即重用。这可以通过使用socket.SO_REUSEADDR
标志来解决。
例如:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind((HOST, PORT))
答案 1 :(得分:4)
您需要为此注册一个钩子,例如:
#!/usr/bin/env python
import signal
import sys
def signal_handler(signal, frame):
# close the socket here
sys.exit(0)
signal.signal(signal.SIGINT, signal_handler)