Article Source: http://www.cnblogs.com/wupeiqi/articles/5040823.html
The Socketserver internally uses IO multiplexing and "multithreading" and "multi-process" to enable the socket service side to process multiple client requests concurrently. That is, when each client requests a connection to the server, the socket server is creating a "thread" or "process" dedicated to all requests from the current client.
Threadingtcpserver
The Soket server implemented by Threadingtcpserver creates a "thread" for each client that is used to interact with the client.
1. Threadingtcpserver Foundation
Using Threadingtcpserver:
- Create a class that inherits from Socketserver.baserequesthandler
- A method called handle must be defined in a class
- Start Threadingtcpserver
The internal invocation process is:
- Start the service-side program
- Executes the tcpserver.__init__ method, creates the server-side socket object and binds the IP and port
- Executes the baseserver.__init__ method, assigning a custom inherited class Myrequesthandle from Socketserver.baserequesthandler to self . Requesthandlerclass
- Executes the Baseserver.server_forever method, while the loop is always listening for client requests to arrive ...
- When a client connection arrives at the server
- Executes the Threadingmixin.process_request method, creating a "thread" to handle the request
- Execute the Threadingmixin.process_request_thread method
- Executes the Baseserver.finish_request method and executes self . Requesthandlerclass () is the construction method that executes the custom Myrequesthandler (automatically calls the constructor of the base class Baserequesthandler, which in turn calls the Handle method of Myrequesthandler)
ImportSocketImportThreadingImportSelectdefprocess (Request, Client_data):Print(Request, CLIENT_DATA) Conn=Request Conn.sendall (bytes ("welcom to 10086", encoding='Utf-8')) Flag=True whileFlag:data= CONN.RECV (1024) ifdata = ='Exit': Flag=Falseelifdata = ='0': Conn.sendall (bytes ("0000", encoding='Utf-8')) Else: Conn.sendall (bytes ("Do it again", encoding="Utf-8")) SK=Socket.socket (socket.af_inet, socket. Sock_stream) Sk.bind (('127.0.0.1', 9999)) Sk.listen (5) whileTrue:r, W, e= Select.select ([sk,],[], [], 1) Print('Looping') ifSkinchr:Print("Get Request") request, Client_address=sk.accept () T= Threading. Thread (target=process, args=(Request, client_address)) T.daemon=False T.start () sk.close ()
As you can see from the streamlined code, Socketserver's threadingtcpserver can handle requests at the same time thanks to the select and threading two things, It is essentially a server-side create a thread for each client, the current thread to handle the corresponding client's request, so, can support simultaneous n client links (long connection).
Forkingtcpserver
The use and execution processes of forkingtcpserver and threadingtcpserver are basically consistent, except that "threads" and "processes" are created internally for the requestor.
Basic use:
Server-side:
ImportSocketserverclassMyServer (socketserver. Baserequesthandler):defhandle (self):#print (Self.request, self.client_address, Self.server)conn =self.request conn.sendall (bytes ('Welcome to connect 10086', encoding='Utf-8')) Flag=True whileFlag:data= CONN.RECV (1024) ifdata = ='Exit': Flag=Falseelifdata = ='0': Conn.sendall (bytes ('Sssssss', encoding='Utf-8')) Else: Conn.sendall (bytes ('Do it again', encoding='UTF8'))if __name__=='__main__': Server= Socketserver. Forkingtcpserver (('127.0.0.1', 8009), MyServer) Server.serve_forever ()
Client:
ImportSocketip_port= ('127.0.0.1', 8009) SK=Socket.socket () sk.connect (Ip_port) sk.settimeout (5) whileTrue:data= SK.RECV (1024) Print("Receive:", data) INP= Input ("Please input:") Sk.sendall (INP)ifINP = ='Exit': Breaksk.close ()
Event-driven
In short, the event driver is divided into two parts: first, registering the event; second, triggering the event.
Custom event-driven framework named: "Kill the Gentleman":
Event_list =[]def Run (): for in event_list: = Event () Obj.execute ()class Basehandler (object): def Execute ( Self): raise Exception ("youmust overwrite execute")
How to use:
from Import Source class MyHandler (source. Basehandler): def execute (self): print("event-drive Execute MyHandler") source.event_list.append (MyHandler) source.run ()
As the code above, event-driven is simply a framework that specifies the order in which a programmer can register an "event" in the original execution order when the framework is in use, so that the registered "event" can be started when the framework executes.
Event-driven sockets
fromTwisted.internetImportProtocol fromTwisted.internetImportreactorclassEcho (protocol. Protocol):defdatareceived (self, data): Self.transport.write (data)defMain (): Factory=protocol. Serverfactory () Factory.protocol=Echo reactor.listentcp (8000, Factory) Reactor.run ()if __name__=='__main__': Main ()
Program execution Flow:
- Running the service-side program
- Create a derived class of protocol echo
- Create a Serverfactory object and encapsulate the Echo class in its Protocol field
- Executes the reactor Listentcp method, using TCP internally. Port creates a socket server object and adds the object to the field _read of the reactor set type
- Executes the reactor run method, executes the while loop internally, and monitors the file descriptor in the _read with a select to see if there is a change in the loop ...
- Client Request Arrival
- Executes the _doreadorwrite method of the reactor, which calls TCP internally through reflection. The Doread method of the Port class, the internal accept client connects and creates an instance of the server object (used to encapsulate the client socket information) and creates an Echo object instance (for processing the request), and then invokes the MakeConnection method of the Echo object instance, creating a The connection is built.
- Executes TCP. The Doread method of the Server class, reading the data,
- Executes TCP. The _datareceived method of the Server class, if the read data content is empty (close link), otherwise, the DataReceived method of the Echo
- DataReceived method for performing Echo
As can be seen from the source code, the above example essentially uses the event-driven approach and the IO multiplexing mechanism for socket processing.
fromTwisted.internetImportReactor, Protocol fromTwisted.web.clientImportGetPage fromTwisted.internetImportreactorImport TimeclassEcho (protocol. Protocol):defdatareceived (self, data): Deferred1= GetPage ('http://cnblogs.com') Deferred1.addcallback (self.printcontents) Deferred2= GetPage ('http://baidu.com') Deferred2.addcallback (self.printcontents) forIinchRange (2): Time.sleep (1) Print 'Execute', IdefExecute (self,data): Self.transport.write (data)defprintcontents (self,content):PrintLen (content), content[0:100],time.time ()defMain (): Factory=protocol. Serverfactory () Factory.protocol=Echo reactor.listentcp (8000, Factory) Reactor.run ()if __name__=='__main__': Main ()
Python Combat socketserver Module