【问题标题】:Shutting down python TCPServer by custom handler通过自定义处理程序关闭 python TCPServer
【发布时间】:2014-03-04 12:03:50
【问题描述】:

我正在尝试通过客户端的 GET 请求从 SocketServer 模块关闭 TCPServer,该请求在窗口关闭时发出,但是以下代码无法启动关闭:

def show_webgl(data):
    import SocketServer
    import SimpleHTTPServer
    from webbrowser import open

    PORT = 8000
    RUNNING = True

    class CustomHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):
        def do_GET(self):
            if self.path=='/atom.json':
                # return data
                return
            elif self.path == '/shutdown':
                httpd.shutdown()
                # quit server, this line is never reached
            else:
                # serve other files
                SimpleHTTPServer.SimpleHTTPRequestHandler.do_GET(self)


    SocketServer.BaseServer.allow_reuse_address = True
    httpd = SocketServer.TCPServer(('0.0.0.0', 8000), CustomHandler)

    print "serving at port", PORT
    open('http://localhost:8000/three.html')
    httpd.serve_forever()     

    print 'closed'

【问题讨论】:

    标签: python socketserver simplehttpserver


    【解决方案1】:

    解决方案 1

    使用 ThreadingHTTPServer。

    class ThreadingHTTPServer(SocketServer.ThreadingMixIn, BaseHTTPServer.HTTPServer):
        allow_reuse_address = True
    

    您的代码:

    import SocketServer
    import SimpleHTTPServer
    import BaseHTTPServer
    from webbrowser import open
    import hanging_threads
    
    PORT = 8005
    RUNNING = True
    
    class CustomHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):
        def do_GET(self):
            print "GET"
            if self.path=='/atom.json':
                # return data
                return
            elif self.path == '/shutdown':
                httpd.shutdown()
                print 'shutdown'
                # quit server, this line is never reached
            else:
                # serve other files
                SimpleHTTPServer.SimpleHTTPRequestHandler.do_GET(self)
    
    
    class ThreadingHTTPServer(SocketServer.ThreadingMixIn, BaseHTTPServer.HTTPServer):
        allow_reuse_address = True
    
    httpd = ThreadingHTTPServer(('0.0.0.0', PORT), CustomHandler)
    
    print "serving at port", PORT
    open('http://localhost:{}/three.html'.format(PORT))
    httpd.serve_forever()
    
    print 'closed'
    

    解决方案 2

    使用关闭启动线程。

    import threading
    threading.Thread(target = httpd.shutdown).start()
    

    上下文

    这就是它挂起的地方。使用hanging_threads.py

        httpd.serve_forever()
      File "C:\Python27\lib\SocketServer.py", line 238, in serve_forever
        self._handle_request_noblock()
      File "C:\Python27\lib\SocketServer.py", line 295, in _handle_request_noblock
        self.process_request(request, client_address)
      File "C:\Python27\lib\SocketServer.py", line 321, in process_request
        self.finish_request(request, client_address)
      File "C:\Python27\lib\SocketServer.py", line 334, in finish_request
        self.RequestHandlerClass(request, client_address, self)
      File "C:\Python27\lib\SocketServer.py", line 649, in __init__
        self.handle()
      File "C:\Python27\lib\BaseHTTPServer.py", line 340, in handle
        self.handle_one_request()
      File "C:\Python27\lib\BaseHTTPServer.py", line 328, in handle_one_request
        method()
      File "C:/Users/wollknaeul/Desktop/httpservertest.py", line 17, in do_GET
        httpd.shutdown()
      File "C:\Python27\lib\SocketServer.py", line 251, in shutdown
        self.__is_shut_down.wait()
      File "C:\Python27\lib\threading.py", line 618, in wait
        self.__cond.wait(timeout)
      File "C:\Python27\lib\threading.py", line 339, in wait
        waiter.acquire()
    

    一些代码:

    def serve_forever(self, poll_interval=0.5):
        """Handle one request at a time until shutdown.
    
        Polls for shutdown every poll_interval seconds. Ignores
        self.timeout. If you need to do periodic tasks, do them in
        another thread.
        """
        self.__is_shut_down.clear()
        try:
            while not self.__shutdown_request:
                # XXX: Consider using another file descriptor or
                # connecting to the socket to wake this up instead of
                # polling. Polling reduces our responsiveness to a
                # shutdown request and wastes cpu at all other times.
                r, w, e = _eintr_retry(select.select, [self], [], [],
                                       poll_interval)
                if self in r:
                    self._handle_request_noblock()
        finally:
            self.__shutdown_request = False
            self.__is_shut_down.set()
    
    def shutdown(self):
        """Stops the serve_forever loop.
    
        Blocks until the loop has finished. This must be called while
        serve_forever() is running in another thread, or it will
        deadlock.
        """
        self.__shutdown_request = True
        self.__is_shut_down.wait()
    

    所以self._handle_request_noblock() 调用你的方法,然后shutdown() 等待服务器离开serve_forever()。不可能发生。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多