2014-03-04 37 views
2

我试图从关机通过客户端一个GET请求的SocketServer模块TCPSERVER,当发射窗口关闭,但下面的代码无法启动关机:通过自定义处理程序关闭蟒蛇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' 

回答

4

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