3

SocketServer.TCPServerに問題があります。スレッドでサーバーを実行しています。Watchdogでディレクトリツリーを監視しています。「on_any_event」が実行されたら、サーバーを停止して再起動する必要があります。残念ながら、SocketServer.TCPServerにアドレスを再利用させることができません。SocketServer.pyファイルを確認しましたが、allow_reuse_addressTrueの場合はsocket.SO_REUSEADDR1に設定されているはずですが、それでも失敗し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 に答える