我尝试在 Python 中使用线程(ThreadingMixIn)对 TCPServer 进行编程。socket.error: [Errno 48] Address already in use
问题是当我尝试再次运行它时,我无法正确关闭它。这是触发问题的 Python 代码的最小示例:
import socket
import threading
import SocketServer
class FakeNetio230aHandler(SocketServer.BaseRequestHandler):
def send(self,message):
self.request.send(message+N_LINE_ENDING)
def handle(self):
self.request.send("Hello\n")
class FakeNetio230a(SocketServer.ThreadingMixIn, SocketServer.TCPServer):
def __init__(self, server_address, RequestHandlerClass):
self.allow_reuse_address = True
SocketServer.TCPServer.__init__(self, server_address, RequestHandlerClass)
if __name__ == '__main__':
for i in range(2):
fake_server = FakeNetio230a(("", 1234), FakeNetio230aHandler)
server_thread = threading.Thread(target=fake_server.serve_forever)
server_thread.setDaemon(True)
server_thread.start()
# might add some client connection here
fake_server.shutdown()
所有主要代码应该做的是启动服务器,关闭它并再次运行它。但它会触发上述错误,因为第一次关闭后套接字尚未释放。
我认为设置self.allow_reuse_address = True
可以解决问题,但没有奏效。当 python 程序完成后,我可以立即再次运行它,它可以启动服务器一次(但不能再次启动两次)。
但是,当我随机化端口(例如替换为)时,问题就消失了,1234
因为1234+i
没有其他服务器正在侦听该地址。
有一个类似的 SO Q从 ThreadingTCPServer 正常关闭,但解决方案(设置allow_reuse_address
为True
不适用于我的代码,我不使用 ThreadingTCPServer)。
我如何必须修改我的代码才能在我的代码中启动服务器两次?
更多信息:我这样做的原因是我想为我的 python 项目运行一些单元测试。这需要提供我的软件应该连接到的(假)服务器。
编辑:
我刚刚找到了对我的问题最正确的答案:我必须fake_server.server_close()
在我的主要执行代码的末尾添加(就在之后fake_server.shutdown()
)。我在TCPServer
实现的源文件中找到了它。它所做的只是self.socket.close()
。