进程终止后,线程上的套接字服务器未释放端口

时间:2012-03-14 11:42:41

标签: python multithreading sockets

以下代码在线程上运行套接字服务器。客户端套接字将'client:hello'发送到服务器,服务器套接字接收并回复'server:world'。

import socket
import threading

def server():
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sock.bind(('127.0.0.1', 12345))
    sock.listen(1)
    req, addr = sock.accept()
    print req.recv(1024)
    req.sendall('server: world')

def client():
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sock.connect(('127.0.0.1', 12345))
    sock.sendall('client: hello')
    print sock.recv(1024)

def main():
    t = threading.Thread(target=server)
    t.start()
    client()

if __name__ == '__main__':
    main()

第一次按预期运行正常,但是从第二次开始,如果您没有等待服务器释放套接字的好几秒钟,并且在Linux机器或Mac上尝试此操作(Windows,请执行此操作)不知道怎么办)你会遇到这个错误:

Traceback (most recent call last):
  File "socket_send_receive.py", line 24, in <module>
    main()
  File "socket_send_receive.py", line 21, in main
    client()
  File "socket_send_receive.py", line 14, in client
    sock.connect(('127.0.0.1', 12345))
  File "<string>", line 1, in connect
socket.error: [Errno 111] Connection refused
Exception in thread Thread-1:
Traceback (most recent call last):
  File "/home/cxuan/python/2.6/lib/python2.6/threading.py", line 532, in __bootstrap_inner
    self.run()
  File "/home/cxuan/python/2.6/lib/python2.6/threading.py", line 484, in run
    self.__target(*self.__args, **self.__kwargs)
  File "socket_send_receive.py", line 6, in server
    sock.bind(('127.0.0.1', 12345))
  File "<string>", line 1, in bind
error: [Errno 98] Address already in use

我正在寻找一些有关这种情况发生的原因,以及是否可以真正解决或应该采用什么样的最佳实践。

我知道已经使用此选项可以解决这个问题,感谢stackoverflow上的其他帖子。

  

socket.SO_REUSEADDR

1 个答案:

答案 0 :(得分:3)

当套接字关闭时,它会以名为STATE_WAIT的状态结束(请参阅this diagram)。当套接字处于此状态时,除非在套接字上设置了SO_REUSEADDR选项,否则没有其他人可以使用相同的地址(ip-number / port对)。

参见例如TCP上的Wikipedia article有关TCP如何工作的更多信息以及different states