1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 | class Py25TCPServer(SocketServer.ThreadingTCPServer): def __init__( self , address_tuple, handler): SocketServer.ThreadingTCPServer.__init__( self , address_tuple, handler) self .__is_shut_down = threading.Event() self .__shutdown_request = False 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: r, w, e = 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() def _handle_request_noblock( self ): """Handle one request, without blocking. I assume that select.select has returned that the socket is readable before this function was called, so there should be no risk of blocking in get_request(). """ try : request, client_address = self .get_request() except socket.error: return if self .verify_request(request, client_address): try : self .process_request(request, client_address) except : self .handle_error(request, client_address) self .close_request(request) |
To make our program work in both Python 2.5 and 2.6+, we can do something like this.
1 2 3 4 5 6 7 8 9 | import sys python_version = sys.version_info server = None if python_version[ 1 ] < 6 : server = Py25TCPServer(( self .host, self .port), MyHandler) else : server = SocketServer.TCPServer(( self .host, self .port), MyHandler) server.server_forever() |