关闭后,直接在代码中再次使用ThreadingMixIn启动TCPServer.(给'地址已经在使用')

pkl*_*aus 5 python sockets shutdown tcpserver

我尝试在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()
Run Code Online (Sandbox Code Playgroud)

所有主要代码应该是启动服务器,关闭它并再次运行它.但它会触发上述错误,因为套接字在第一次关闭后尚未释放.

我认为这个设置self.allow_reuse_address = True可以解决问题,但这不起作用.当python程序完成后,我可以立即再次运行它,它可以启动服务器一次(但不是两次).
然而,当我随机端口(更换问题了12341234+i为例),因为没有其他服务器监听该地址.

有一个类似的SO Q 从ThreadingTCPServer正常关闭,但解决方案(设置allow_reuse_addressTrue不适用于我的代码,我不使用ThreadingTCPServer).

我如何修改我的代码才能在我的代码中启动服务器两次?

更多信息:我这样做的原因是我想为我的python项目运行一些单元测试.这需要提供我的软件应该连接的(假)服务器.

编辑:
我刚刚找到了问题的最正确答案:我必须fake_server.server_close()在主执行代码的末尾添加(紧接着fake_server.shutdown()).我在实现的源文件中找到了它TCPServer.它所做的一切都是self.socket.close().

小智 4

不知何故,fake_server当您分配给它时不会解除绑定(在for语句的第一行中)。

要解决这个问题,只需fake_server在循环末尾删除:

        del fake_server # force server to unbind
Run Code Online (Sandbox Code Playgroud)