首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何重启BaseHTTPServer实例?

如何重启BaseHTTPServer实例?
EN

Stack Overflow用户
提问于 2012-05-22 23:58:53
回答 2查看 3.6K关注 0票数 2

这就是我所拥有的:

http.py:

代码语言:javascript
复制
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()

然后在另一个文件中,重新启动它:

代码语言:javascript
复制
def restartHTTP(self):
    try:
        self.httpserver.stop()
        reload(http)
        self.httpserver = http.HTTPServer(80)
        self.httpserver.serve()
    except:
        traceback.print_exc()

这给了我一个地址已在使用中的错误,所以看起来HTTP服务器没有正确停止。我还需要做些什么来阻止它?

编辑:

我调用restartHTTP的地方:

代码语言:javascript
复制
def commandHTTPReload(self, parts, byuser, overriderank):
    self.client.factory.restartHTTP()
    self.client.sendServerMessage("HTTP server reloaded.")

我知道命令正在执行,因为我得到了它应该发送的消息。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-05-23 00:59:56

你只需要让操作系统知道你真的想在关闭端口后立即重用它。正常情况下,它会处于关闭状态一段时间,以防出现任何额外的数据包。您可以使用SO_REUSEADDR执行此操作:

代码语言:javascript
复制
mysocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

..after正在打开mysocket。使用HTTPServer实现这一点的一个好方法是在被覆盖的server_bind方法中:

代码语言:javascript
复制
def server_bind(self):
    HTTPServer.server_bind(self)
    self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

编辑:仔细查看您的代码后,我发现您的线程模型也可能在这里造成问题。您正在关闭主(?)中的插座当另一个线程正在等待同一套接字上的连接时(在accept()中)。这种安排没有定义良好的语义,我相信它在不同的OSes上做不同的事情。在任何情况下,这都是您应该避免的事情,以便最大限度地减少混淆(在多线程程序中已经有很多这样的事情了)。在获得连接并处理其请求之前,旧线程实际上不会消失(因为在此之前它不会重新检查self.run ),因此端口可能在此之后才可重新绑定。

对此并没有一个简单的解决方案。您可以在线程之间添加一个通信管道,然后在服务器线程中使用select()/poll()来等待其中任何一个线程上的活动,或者您可以在短时间后使accept()调用超时,以便更频繁地检查self.run。或者,您可以让主线程连接到侦听套接字本身。但是,无论您做什么,您都可能正在接近复杂程度,您应该考虑使用“真正的”httpd或网络框架,而不是使用自己的框架: apache、lighttpd、Tornado、Twisted等。

票数 3
EN

Stack Overflow用户

发布于 2017-02-13 23:51:48

要优雅地停止HTTPServer并关闭套接字,应该使用:

代码语言:javascript
复制
# Start server
httpd = HTTPServer(...)
httpd.serve_forever()
# Stop server
httpd.shutdown()
httpd.server_close()
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/10705680

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档