我在CentOS 6.4 / 64位下运行Python协议。我在哪里有TCP服务器端口7007.在某些情况下,如更新新版本或维护或动态重启刷新缓冲区我需要重新启动应用程序:
server.py:
class AServer(threading.Thread):
def __init__(self, port):
threading.Thread.__init__(self)
self.port = port
def run(self):
host = ''
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((host, self.port))
print bgcolors.BOOT
s.listen(1)
conn, addr = s.accept()
print bgcolors.OK + 'contact', addr, 'on', self.now()
while 1:
try:
data = conn.recv(1024)
except socket.error:
print bgcolors.OK + 'lost', addr, 'waiting..'
s.listen(1)
conn, addr = s.accept()
print bgcolors.OK + 'contact', addr, 'on', self.now()
continue
if not data:
.....
...
t = AServer(7007)
t.start()
动态重启(预计在1秒内运行)但失败:
$ ps aux | awk '/server.py/ {print $2}' | head -1 | xargs kill -9;
$ nohup python /var/tmp/py-protocol/server.py &
[root@IPSecVPN protocol]# python server.py
Exception in thread Thread-1:
Traceback (most recent call last):
File "/usr/lib64/python2.6/threading.py", line 532, in __bootstrap_inner
self.run()
File "server.py", line 236, in run
s.bind((host, self.port))
File "<string>", line 1, in bind
error: [Errno 98] Address already in use
答案 0 :(得分:6)
您的套接字处于TIME_WAIT状态,这就是即使您的程序已退出,地址仍在使用的原因。您可以在套接字退出TIME_WAIT状态之前在套接字上设置SO_REUSEADDR以重复使用它。 Python documentation建议如下:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind((HOST, PORT))
答案 1 :(得分:1)
好吧,TCP有一个TIMEWAIT定时器,可以连接一段时间(大多数操作系统大约需要2分钟)。因此,如果您已经有一个端口绑定并连接,那么关闭它可能会使其处于TIMEWAIT状态。更确切地说,只有TCP连接的一端处于TIMEWAIT状态。
这是关于TIMEWAIT的一个很好的讨论:What is the cost of many TIME_WAIT on the server side?
同意@clj解决方案,设置SO_REUSEADDR是一个好主意(+1)。