標籤:format 接受 pass default oca and sock target example
使用ThreadingMixIn類的特點: 線上程間共用應用的狀態,與使用ForkingMixIn類相比避免處理序間通訊的複雜操作。
代碼如下:
1 #! /usr/bin/python 2 3 import os 4 import socket 5 import threading 6 import SocketServer 7 8 SERVER_HOST = ‘localhost‘ 9 SERVER_PORT = 010 BUF_SIZE = 102411 12 def client(ip, port, message):13 """A client to test threading mixin server"""14 sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)15 sock.connect((ip, port))16 try:17 sock.sendall(message)18 response = sock.recv(BUF_SIZE)19 print "Client received: %s" % response20 finally:21 sock.close()22 23 24 class ThreadedTCPRequestHandler(SocketServer.BaseRequestHandler):25 """An example of threaded TCP request handler """26 def handle(self):27 data = self.request.recv(1024)28 current_thread = threading.current_thread()29 response = "%s: %s" % (current_thread.name, data)30 self.request.sendall(response)31 32 class ThreadedTCPServer(SocketServer.ThreadingMixIn, SocketServer.TCPServer):33 """Nothing add here, inherited everything from parenets"""34 pass35 36 if __name__ == ‘__main__‘:37 #run server38 server = ThreadedTCPServer((SERVER_HOST, SERVER_PORT), ThreadedTCPRequestHandler)39 ip, port = server.server_address40 41 # start a thread with the server, one thread per request42 server_thread = threading.Thread(target=server.serve_forever)43 # Exit the server thread when the main thread exits44 server_thread.daemon = True45 server_thread.start()46 print "Server loop running on thread: %s" % server_thread.name47 48 # run clients49 client(ip, port, "Hello from client1")50 client(ip, port, "Hello from client2")51 client(ip, port, "Hello from client3")52 53 #server cleanup54 server.shutdown()55
注意點1,在寫ThreadedTCPRequestHandler類中的方法handle的時候將handle寫為了handler,結果在執行程式後,顯示伺服器返回給用戶端的資訊為空白,原因是handle方法是ThreadedTCPRequestHandler類所繼承的BaseRequestHandler類的類方法,由於BaseRequestHandler類的handle方法預設行為是啥也不做,所以要覆寫handle方法來處理接受用戶端訊息,處理用戶端請求,如果寫為handler則在程式中預設調用了父類BaseRequestHandler的handle方法,但是啥也沒做,所以顯示伺服器返回資訊為空白。
-
RequestHandler.handle()
-
This function must do all the work required to service a request. The default implementation does nothing. Several instance attributes are available to it; the request is available as self.request; the client address as self.client_address; and the server instance as self.server, in case it needs access to per-server information.
The type of self.request is different for datagram or stream services. For stream services, self.request is a socket object; for datagram services, self.request is a pair of string and socket. However, this can be hidden by using the request handler subclasses StreamRequestHandler or DatagramRequestHandler, which override the setup() and finish() methods, and provide self.rfile and self.wfile attributes. self.rfile and self.wfile can be read or written, respectively, to get the request data or return data to the client.
注意點2,關於線程對象的setDaemon屬性,為True表示伺服器線程為後台線程,當沒有活動串連到後台線程時,程式執行完畢自動結束,當沒有活動的非後台線程活動時,執行完畢程式才會自動結束。對於本代碼,具體表現是如果在setDaemon為True的狀態,不執行伺服器通訊端的shutdown(),程式執行完一樣會自動結束,而setDaemon為False的狀態, 則一定要執行shutdown(),程式才會自動終止。
Python網路編程(二)通過ThreadingMixIn實現多線程非同步通訊端程式