ThreadingTCPServer 如何设置端口重用

来源:互联网 发布:voa听力软件下载 编辑:程序博客网 时间:2024/05/17 06:06

一个典型的TCPServer的建立

    #ThreadingTCPServer从ThreadingMixIn和TCPServer继承      #class ThreadingTCPServer(ThreadingMixIn, TCPServer): pass      server = ThreadingTCPServer(addr, MyStreamRequestHandlerr)      server.serve_forever()

查看SocketServer.py的实现

    def __init__(self, server_address, RequestHandlerClass, bind_and_activate=True):        """Constructor.  May be extended, do not override."""        BaseServer.__init__(self, server_address, RequestHandlerClass)        self.socket = socket.socket(self.address_family,                                    self.socket_type)        if bind_and_activate:            self.server_bind()            self.server_activate()    def server_bind(self):        """Called by constructor to bind the socket.        May be overridden.        """        if self.allow_reuse_address:            self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)        self.socket.bind(self.server_address)        self.server_address = self.socket.getsockname()

可以看到,在init初始化里面就已经进行了bind操作,之后再单独设置server的socket选项将不起作用,这就是为什么很多人遇到了直接使用对象的setsockopt方法感觉没有生效,端口有TIME_WAIT的状态,再次运行程序仍然会报Address Already In Use 的错误。

server.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

解决方案:

方案一

继承SocketServer.ThreadingTCPServer,在init之前设置allow_reuse_address = True(默认为False)

class EchoServer(SocketServer.ThreadingTCPServer):    allow_reuse_address = True    daemon_threads = True    def __init__(self, server_address, RequestHandlerClass):        """Set up an initially empty mapping between a user' s nickname        and the file-like object used to send data to that user."""        SocketServer.ThreadingTCPServer.__init__(self, server_address, RequestHandlerClass)

方案二

重载Server_bind,在bind之前设置socket选项

    def server_bind(self):        """Called by constructor to bind the socket.        May be overridden.        """        self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)        self.socket.bind(self.server_address)        self.server_address = self.socket.getsockname()
0 0
原创粉丝点击