1.socketserver Modules and Classes
Socketserver is an advanced module in the standard library, with the goal of simplifying many boilerplate code (the code necessary to create network clients and servers)
This module encapsulates the various classes required for socket programming and can now use classes to write applications.
Because handling transactions in an object-oriented manner helps to organize data and logically puts functionality in the right place, the application is now time-driven, which means that it will only work when the time in the system occurs.
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.
The Socketserver module simplifies the writing of Web servers, and Python abstracts Web services into two main classes
One is the server class that handles connection-related network operations
The other is the RequestHandler class, which handles data-related operations. And two mixin classes are available to extend the Server for multi-process or multi-threaded.
Description of the class
1.BaseServer contains the core server functions and hooks for the Mix-in class, and is used only for derivation, which does not create an instance of the class; You can create an instance of the class with TCPServer or Udpserver
2.tcpserver/udpserver-based network synchronization TCP/UDP server
3.unixstreamserver/unixdatagramserver file-based synchronization of TCP/UDP servers
4.forkingmixin/threadingmixin core dispatching or threading function; only used for Mix-in class with a server class to implement some asynchrony; You cannot instantiate this class directly
Combination of 5.threadingtcpserver/threadingudpserver ThreadingMixIn and Tcpserver/udpserver
Combination of 6.forkingtcpserver/forkingudpserver Forkingmixin and Tcpserver/udpserver
7.BaseRequestHandler contains the core functions of processing server requests, and is used only for derivation, so that instances of this class cannot be created; You can create an instance of the class with Streamrequesthandler or Datagramrequesthandler
8.streamrequesthandler/datagramrequesthandler Implementing a service processor for the TCP/UDP server
The inheritance relationship of four basic classes
+------------+| Baseserver |+------------+ | V+-----------+ +------------------+| TCPServer |------->| Unixstreamserver |+-----------+ +------------------+ | V+-----------+ +--------------------+| Udpserver |------->| Unixdatagramserver |+-----------+ +--------------------+
These four classes use "synchronization" to process a request. You can start processing new requests only after you have processed all the requests! Not suitable for situations where a single request takes a lot of time to process. Because it takes a lot of computational time, or because it returns a large amount of data, the client processing speed becomes slow. The workaround is to create a separate process or thread to process each request. The forkingmixin and threadingmixin combinations within the class can support "asynchronous" operations.
So, to get your socketserver together, you must choose to use one of the following multiple concurrency classes
Classsocketserver.
ForkingTCPServer
Classsocketserver.
ForkingUDPServer
Classsocketserver.
ThreadingTCPServer
Classsocketserver.
ThreadingUDPServer
2.ThreadingTCPServer
The Soket server implemented by Threadingtcpserver creates a " thread " For each client that is used to interact with the client.
First, the request handler class must be created by inheriting the Baserequesthandler class and overriding the handle () method; This method will process the incoming request.
Second, you must instantiate one of the server classes and pass it to the server's address and request handler class.
Then, call the Handle_request () or Serve_forever () method of the server object to process one or more requests.
Finally, call Server_close () to close the socket.
Threadingtcpserver---->tcpserver ------>baseserver------>requesthandlerclass | (__init__) server_forever | Finish_request |-----> threadingmixin.process_request () |-----> Threadingmixin.process_request_thread ()
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 to assign 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)
Service side
#-*-coding:utf-8-*-#2017/11/25 20:15ImportSocketserverclassMyServer (socketserver. Baserequesthandler):defhandle (self):#Print Self.request,self.client_address,self.serverconn =self.request conn.sendall (bytes ('Welcome to call 10086,0 for manual service.', encoding='UTF8')) Flag=True whileFlag:data= CONN.RECV (1024) Data= str (data, encoding='UTF8') ifdata = ='Exit': Flag=Falseelifdata = ='0': Conn.sendall (bytes ('through may be recorded', encoding='UTF8')) Else: Conn.sendall (bytes ('Please re-enter.', encoding='UTF8'))if __name__=='__main__': Server= Socketserver. Threadingtcpserver (('127.0.0.1', 8009), MyServer) Server.serve_forever ()
Server-side Source simulation
1 #-*-coding:utf-8-*-2 #2017/11/25 20:373 ImportSocket4 ImportThreading5 ImportSelect6 7 8 defprocess (Request, client_address):9 Print(request,client_address)Tenconn =Request OneConn.sendall (Bytes ('Welcome to call 10086, please input 1xxx,0 to manual service.', encoding='UTF8')) AFlag =True - whileFlag: -data = CONN.RECV (1024) thedata = str (data, encoding='UTF8') - ifdata = ='Exit': -Flag =False - elifdata = ='0': + Print(data) -Conn.sendall (Bytes ('through may be recorded. Balabala a big push.', encoding='UTF8')) + Else: AConn.sendall (Bytes ('Please re-enter.', encoding='UTF8')) at -SK =Socket.socket (socket.af_inet, socket. SOCK_STREAM) -Sk.bind (('127.0.0.1', 8002)) -Sk.listen (5) - - whileTrue: inR, W, E = Select.select ([sk,],[],[],1) - Print('Looping') to ifSkinchr: + Print('GET Request') -Request, client_address =sk.accept () thet = Threading. Thread (target=process, args=(Request, client_address)) *T.daemon =False $ T.start ()Panax NotoginsengSk.close ()
View Code
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).
Client
#-*-coding:utf-8-*-#2017/11/25 20:16ImportSocketip_port= ('127.0.0.1', 8009) SK=Socket.socket () sk.connect (Ip_port) sk.settimeout (5) whileTrue:data= SK.RECV (1024) Data= str (data, encoding='UTF8') Print('Receive:', data) INP= Input ('Please input:') Sk.sendall (bytes (inp,encoding="UTF8")) ifINP = ='Exit': Breaksk.close ()
Forkingtcpserver just the code in the Threadingtcpserver instance:
Socketserver's Threadingtcpserver can handle requests at the same time thanks to the select and os.fork two things, essentially creating a process on the server side for each client, Currently the newly created process is used to handle requests from the corresponding client, so you can support simultaneous n client links (long connections).
server
=
SocketServer.ThreadingTCPServer((
‘127.0.0.1‘
,
8009
),MyRequestHandler)
变更为:
server
=
SocketServer.ForkingTCPServer((
‘127.0.0.1‘
,
8009
),MyRequestHandler)
socketserver.
3.class BaseServer
(server_address, requesthandlerclass) mainly have the following methods
Class Socketserver. Baseserver (Server_address,requesthandlerclass)
This is the superclass of all server objects in the module. It defines the interfaces given below, but does not implement most of the methods that are done in subclasses. These two parameters are stored in the corresponding server_address and Requesthandlerclass properties.
Fileno ()
Returns the integer file descriptor of the socket that the server is listening on. This function is usually passed to the selector, allowing multiple servers to be monitored in the same process.
Handle_request ()
Process a request. The function calls the following methods sequentially: Get_request (), Verify_request (), and Process_request (). If the user-supplied handle () method of the handler class throws an exception, the server's Handle_error () method is called. If no request is received within the timeout second, handle_timeout () is called and Handle_request () is returned.
Serve_forever (poll_interval = 0.5)
Processes the request until an explicit close () request is processed. Polls close each poll_interval second. The timeout attribute is ignored. It also calls Service_actions (), which subclasses or mixin can use to provide operations specific to a given service. For example, the Forkingmixin class uses service_actions () to clean up the zombie subprocess.
Changes were made in version 3.3: The service_actions call was added to the Serve_forever method.
Service_actions ()
This is called in the Serve_forever () loop. This method can be overridden by a quilt class or mixin class to perform operations specific to a given service, such as a cleanup operation.
What's new in version 3.3
Shutdown ()
Tell the Serve_forever () loop to stop and wait until it ends.
Server_close ()
Clean up the server. may be overwritten.
Address_family
The protocol family to which the server socket belongs. The usual examples are socket.af_inet and Socket.af_unix.
Requesthandlerclass
A user-supplied request handler class; An instance of this class is created for each request.
Server_address
The address on which the server is listening. The address format varies by protocol family, see the documentation for the socket module for more information. For an Internet protocol, this is a tuple containing a string of addresses, and an integer port number: (' 127.0.0.1 ', 80).
Socket
The server listens for incoming requests to the socket object.
The server class supports the following class variables:
Allow_reuse_address
Whether the server allows the reuse of addresses. This defaults to false, which can be set in the subclass to change the policy.
Request_queue_size
The size of the request queue. If a single request takes a long time to process, all requests that arrive when the server is busy are placed in a queue, up to request_queue_size requests. Once the queue is full, further requests from the client will receive a "connection denied" error. The default value is usually 5, but this can be overridden by subclasses.
Socket_type
The type of socket used by the server; Socket. Sock_stream and Socket.sock_dgram are two common values.
Timeout
The time-out duration in seconds, or time-out if no time-out is required. If Handle_request () does not receive an incoming request within the time-out period, the Handle_timeout () method is called.
There are many server methods that can be overridden by subclasses of basic server classes such as TCPServer, which are not useful to external users of server objects.
Finish_request ()
The request is actually processed by instantiating the Requesthandlerclass and calling its handle () method.
Get_request ()
You must accept the request from the socket and return the 2-tuple and the address of the client that contains the new socket object that you want to use to communicate with the client.
Handle_error (request,client_address)
This function is called if the handle () method of the Requesthandlerclass instance throws an exception. The default action is to print back to standard output and continue processing more requests.
Handle_timeout ()
When the Timeout property is set to a value other than none, the function is called, the time-out is past, and no request is received. The default action of a derived server is to collect the state of any child processes exiting, and in a thread server, this method does nothing.
Process_request (request,client_address)
Call Finish_request () to create an instance of the Requesthandlerclass. If necessary, this function can create a new process or thread to handle the request; Both the Forkingmixin and the ThreadingMixIn classes do this.
Server_activate ()
Called by the server's constructor to activate the server. The default behavior of the TCP server is to call listen () only on the server socket. may be overwritten.
Server_bind ()
Called by the server's constructor to bind the socket to the desired address. may be overwritten.
Verify_request (request,client_address)
You must return a Boolean value, or if the value is true,
Socketserver of the Python Network programming chapter