python - 通过自定义处理程序关闭 python TCPServer

标签 python socketserver simplehttpserver

我试图通过客户端在关闭窗口时发出的 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'

最佳答案

解决方案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()。不可能发生。

关于python - 通过自定义处理程序关闭 python TCPServer,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22171441/

相关文章:

python - 如何在一台 Apache 服务器上部署多个 Python 2 和 3 Django 项目?

python - 在图像中组合水平对齐的多边形

c - 在从客户端发送任何消息之前,无法将消息从服​​务器端打印到客户端

Python 简单的 HTTPS 转发器

Python:SimpleHTTPServer 内容长度错误

Python SimpleHTTPServer 404 页面

python - CUDA 初始化 : Unexpected error from cudaGetDeviceCount()

sockets - TCP/UDP 套接字和 Websocket 可以相互通信吗?

javascript - 无法让 SimpleHTTPRequestHandler 响应 AJAX

python - SciKit Learn 并行处理 0.17 到 0.18 (Python 2.7)