3

我遇到了 SocketServer.TCPServer 的问题。我正在线程中运行服务器。使用 Watchdog 观察目录树。当“on_any_event”运行时,我需要关闭服务器并重新启动它。不幸的是,我无法让 SocketServer.TCPServer 重用该地址。我检查了 SocketServer.py 文件,如果allow_reuse_address是 True 它应该设置socket.SO_REUSEADDR为 1。但它仍然失败error: [Errno 98] Address already in use 。在重试之前睡 10 秒也无济于事。有什么帮助吗?

class Server(SocketServer.TCPServer):
    allow_reuse_address = True

class ChangeHandler(FileSystemEventHandler):
    def __init__(self):
        FileSystemEventHandler.__init__(self)
        self.rebuild()

    def on_any_event(self, event):
        print event
        self.httpd.shutdown()
        self.t.join()
        self.rebuild()

    def rebuild(self):
        self.t, self.httpd = runserver()

def runserver():
    handler = SimpleHTTPServer.SimpleHTTPRequestHandler
    httpd = Server((HOST, PORT), handler, bind_and_activate=False)
    httpd.server_bind()
    httpd.server_activate()
    t = threading.Thread(target=httpd.serve_forever)
    t.daemon = True
    t.start()
    print "Live at http://{0}:{1}".format(HOST, PORT)
    return t, httpd

if __name__ == "__main__":
    handler = ChangeHandler()
    observer = Observer()
    observer.schedule(handler, path=ROOT, recursive=True)
    observer.start()

    try:
        while True:
            time.sleep(1)
    except KeyboardInterrupt:
        observer.stop()
    observer.join()
4

2 回答 2

4

TCPServer 实现了未记录的方法 server_close(),在事件处理程序中的 self.t.join() 之前或之后调用它,因为这将实际关闭底层套接字。正如所写的那样,您似乎可能会泄漏套接字。

def on_any_event(self, event):
    print event
    self.httpd.shutdown()
    self.httpd.server_close() # actually close the socket
    self.t.join()
    self.rebuild()

在您关闭套接字之前,地址实际上正在使用中。

于 2012-09-06T21:10:26.663 回答
3

添加一个self.httpd.server_close()之后self.httpd.shutdown()就可以了。

于 2012-09-06T21:02:29.840 回答