2012-09-06 25 views
3

我遇到了SocketServer.TCPServer的問題。我在一個線程中運行一個服務器。用看門狗看一個目錄樹。當「on_any_event」運行時,我需要取下服務器並重新啓動它。不幸的是,我無法讓SocketServer.TCPServer重新使用該地址。我已經檢查了SocketServer.py文件,如果allow_reuse_address是True,它應該將socket.SO_REUSEADDR設置爲1.但它仍然會與error: [Errno 98] Address already in use 失敗。在重試之前睡10秒也沒有幫助。任何幫助?無法在SocketServer.TCPServer中重複使用套接字

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() 
+0

你在哪個平臺上:Linux,Windows,OS X?應該不是真的很重要,但是... ... Linux的 – grieve

+0

。 Ubuntu 11.04。 Python 2.7.1 – vascop

+0

「我需要取下服務器並重新啓動它」。爲什麼? – EJP

回答

3

self.httpd.shutdown()後加了self.httpd.server_close()這個技巧。

+0

打敗我吧。 :) – grieve

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() 

在關閉套接字之前,地址實際上正在使用中。

+0

未記錄的方法總是很好。謝謝您的幫助 :) – vascop