这就是我所拥有的:
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.")我知道命令正在执行,因为我得到了它应该发送的消息。
发布于 2012-05-23 00:59:56
你只需要让操作系统知道你真的想在关闭端口后立即重用它。正常情况下,它会处于关闭状态一段时间,以防出现任何额外的数据包。您可以使用SO_REUSEADDR执行此操作:
mysocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)..after正在打开mysocket。使用HTTPServer实现这一点的一个好方法是在被覆盖的server_bind方法中:
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等。
发布于 2017-02-13 23:51:48
要优雅地停止HTTPServer并关闭套接字,应该使用:
# Start server
httpd = HTTPServer(...)
httpd.serve_forever()
# Stop server
httpd.shutdown()
httpd.server_close()https://stackoverflow.com/questions/10705680
复制相似问题