簡體   English   中英

如何重新啟動BaseHTTPServer實例?

[英]How can I restart a BaseHTTPServer instance?

這就是我所擁有的:

http.py:

class HTTPServer():

    def __init__(self, port):
        self.port = port
        self.thread = None
        self.run = True
    def serve(self):
        self.thread = threading.Thread(target=self._serve)
        self.thread.start()
    def _serve(self):
        serverAddress = ("", self.port)
        self.server = MyBaseHTTPServer(serverAddress,MyRequestHandler)
        logging.log(logging.INFO, "HTTP server started on port %s"%self.port)
        while self.run:
            self.server.handle_request()
    def stop(self):
        self.run = False
        self.server.server_close()

然后在另一個文件中,重新啟動它:

def restartHTTP(self):
    try:
        self.httpserver.stop()
        reload(http)
        self.httpserver = http.HTTPServer(80)
        self.httpserver.serve()
    except:
        traceback.print_exc()

這給了我一個地址已經在使用中的錯誤,因此看來HTTP服務器沒有正確停止。 我還需要做什么來阻止它?

編輯:

我在哪里調用restartHTTP:

def commandHTTPReload(self, parts, byuser, overriderank):
    self.client.factory.restartHTTP()
    self.client.sendServerMessage("HTTP server reloaded.")

我知道命令正在執行,因為我得到了應該發送的消息。

您只需要讓操作系統知道您確實確實想在關閉端口后立即重用該端口。 通常情況下,它將在關閉狀態下保持一段時間,以防出現額外的數據包。 您可以使用SO_REUSEADDR進行此操作:

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

..打開mysocket之后。 使用HTTPServer進行此操作的一個好地方可能是在重寫的server_bind方法中:

def server_bind(self):
    HTTPServer.server_bind(self)
    self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

編輯:仔細查看了您的代碼后,我發現您的線程模型也可能在這里引起問題。 您正在關閉main(?)線程中的套接字,而另一個線程正在等待同一套接字(在accept() )的連接。 這種安排沒有明確定義的語義,我相信它在不同的OS上做不同的事情。 無論如何,為了最大程度地減少混亂(在多線程程序中已經解決了很多混亂),您應該避免這種情況。 您的舊線程只有在獲得連接並處理其請求之后才會真正消失(因為在此之前它不會重新檢查self.run ),因此直到那之后該端口才可能重新綁定。

確實沒有一個簡單的解決方案。 您可以在線程之間添加通信管道,然后在服務器線程中使用select() / poll()等待它們中任何一個的活動,或者可以在很短的時間后使accept()調用超時,以便self.run得到更頻繁的檢查。 也可以將主線程連接到偵聽套接字本身。 但是無論您做什么,您都可能已經達到了應該使用“真實的” httpd或網絡框架而不是自己動手的復雜程度:apache,lighttpd,Tornado,Twisted等。

為了正常停止HTTPServer並關閉套接字,應使用:

# Start server
httpd = HTTPServer(...)
httpd.serve_forever()
# Stop server
httpd.shutdown()
httpd.server_close()

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM