Python uses the SocketServer module to compile the basic server program tutorial, pythonsocketserver
SocketServer simplifies the compilation of network servers. It has four classes: TCPServer, UDPServer, UnixStreamServer, and unixw.ramserver. These four classes are processed synchronously. In addition, the ForkingMixIn and ThreadingMixIn classes support Asynchronization.
Create a server. First, you must create a request processing class, which is a subclass of BaseRequestHandler and reload its handle () method. Second, you must instantiate a server class and pass in the server address and request processing program class. Finally, call handle_request () (generally call other event loops or use select () or serve_forever ().
When integrating the ThreadingMixIn class, you must handle exceptions and disable them. Daemon_threads indicates whether the server is waiting for thread termination. If the threads are independent of each other, it must be set to True. The default value is False.
No matter what network protocol is used, the server class has the same external methods and attributes.
In Python3, this module is the socketserver module. In Python 2, this module is the SocketServer module. Therefore, when using import to import data, import data in different situations. Otherwise, an error is returned. The import code is as follows:
try: import socketserver #Python 3except ImportError: import SocketServer #Python 2
The SocketSerror module contains many classes that simplify the implementation of socket servers in TCP, UDP, and UNIX domains.
I. Processing Procedures
To use this module, you must define a handler class that inherits from the base class BaseRequestHandler. The BaseRequestHandler class instance h can implement the following methods:
1. h. handle () calls this method to perform actual request operations. This function can be called without any parameters, but several instance variables contain useful values. H. request contains the request, h. client_address contains the client address, and h. server contains the instance that calls the processing program. For data stream services such as TCP, the h. request attribute is a socket object. For the datagram service, it is a byte string containing the received data.
2. h. setup () is called before handle. By default, it does not perform any operations. If you want the server to implement more connection settings (such as setting up an SSL connection), you can do so here.
3. Call h. finish () to clear the handle. By default, it does not perform any operations. If neither setup () nor handle () generates an exception, you do not need to call this method.
If you know that an application can only manipulate data stream-oriented connections (such as TCP), you should inherit from StreamRequestHandler instead of BaseRequestHandler. The StreamRequestHandler class has two attributes. h. wfile is a class file object that writes data to the client, and h. rfile is a class file object that reads data from the client.
If you want to write a processing program for data packet operations and continuously return the response to the sender, it should inherit from mongoramrequesthandler. It provides the same class interface as StramRequestHandler.
Ii. Servers
To use a handler, you must insert it into the server object. Defines four basic server classes.
(1) TCPServer (address, handler) supports IPv4 TCP server. address is a (host, port) tuples. Handler is an instance of the subclass of the BaseRequestHandler or StreamRequestHandler class.
(2) UDPServer (address, handler) supports IPv4 UDP server. address and handler are similar to TCPServer.
(3) UnixStreamServer (address, handler) uses UNIX domain socket to implement a server for data stream protocol and inherits from TCPServer.
(4) UnixDatagramServer (address, handler) uses UNIX domain socket to implement the datagram protocol server, inherited from UDPServer.
All four server classes have the following methods and variables:
1. s. socket is used to pass in the request's socket object.
2. s. sever_address: the address of the listening server. For example, tuples ("127.0.0.1", 80)
3. The request handler class s. RequestHandlerClass is passed to the server constructor and provided by the user.
4. s. serve_forever () processes unlimited requests
5. s. shutdown () stops the serve_forever () loop.
6. s. fileno () returns the integer file descriptor of the server socket. This method can effectively use server instances through polling operations (such as the select () function.
Iii. Custom Server
Servers often need special configurations to handle different network address families, super-period, concurrency, and other functions. You can inherit the above four basic server classes to customize them.
More server functions can be obtained through the mixing class, which is also added and released through the process or thread branch. To achieve concurrency, the following classes are defined:
(1) ForkingMixIn is a hybrid method that adds UNIX process branches to the server. This method allows the server to serve multiple customers.
(2) ThreadingMixIn can be used to modify the server's mixing class and serve multiple clients using a thread.
To add these features to the server, you can use multi-inheritance. The mixed classes are listed first.
Because concurrent servers are commonly used, SocketServer predefines the following server classes to define them:
(1) ForkingUDPServer (address, handler)
(2) ForkingTCPServer (address, handler)
(3) ThreadingUDPServer (address, handler)
(4) ThreadingTCPServer (address, handler)
The above is a bit messy and is summarized as follows:
The classes in the SocketServer module mainly include the following:
1. BaseServer includes the server's core functions and the mix-in hook function. This class is mainly used for derivation. Do not directly generate class objects of this class. You can use the TCPServer and UDPServer classes.
2. TCPServer basic network synchronization TCP Server
3. UDPServer basic network synchronization UDP Server
4. ForkingMixIn implements the core process function and is used to mix with the server class to provide some asynchronous features. Do not directly generate objects of this class.
5. ThreadingMixIn implements the core threading function and is used to mix with server classes to provide some asynchronous features. Do not directly generate objects of this class.
6. Combination of ForkingTCPServer ForkingMixIn and TCPServer
7. Combination of ForkingUDPServer ForkingMixIn and UDPServer
8. BaseRequestHandler
9. An implementation of the StreamRequestHandler TCP request processing class
10. An implementation of the DataStreamRequestHandler UDP request processing class
Now all the complicated transactions have been encapsulated into the class, and you can simply use the class.
Iv. Instances
1. TCP server code written using the SocketServer module:
#! /Usr/bin/env python # coding = UTF-8 "SocketServer is used to implement a simple TCP server" from SocketServer import (TCPServer, StreamRequestHandler as SRH) from time import ctimeclass MyRequestHandler (SRH): def handle (self): print "connected from", self. client_address self. wfile. write ("[% s] % s" % (ctime (), self. rfile. readline () tcpSer = TCPServer ("", 10001), MyRequestHandler) print "waiting for connection" tcpSer. serve_forever () TCP client code :#! /Usr/bin/env python # coding = utf-8from socket import * BUFSIZE = 1024 # create a new connection each time while True: tcpClient = socket (AF_INET, SOCK_STREAM) tcpClient. connect ("localhost", 10001) data = raw_input (">") if not data: break tcpClient. send ("% s \ r \ n" % data) data1 = tcpClient. recv (BUFSIZE) if not data1: break print data1.strip () tcpClient. close ()
2. Asynchronous Server implementation
Example of ThreadingMixIn:
import socketimport threadingimport SocketServerclass ThreadedTCPRequestHandler(SocketServer.BaseRequestHandler): def handle(self): data = self.request.recv(1024) cur_thread = threading.current_thread() response = "{}: {}".format(cur_thread.name, data) self.request.sendall(response)class ThreadedTCPServer(SocketServer.ThreadingMixIn, SocketServer.TCPServer): passdef client(ip, port, message): sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.connect((ip, port)) try: sock.sendall(message) response = sock.recv(1024) print "Received: {}".format(response) finally: sock.close()if __name__ == "__main__": # Port 0 means to select an arbitrary unused port HOST, PORT = "localhost", 0 server = ThreadedTCPServer((HOST, PORT), ThreadedTCPRequestHandler) ip, port = server.server_address # Start a thread with the server -- that thread will then start one # more thread for each request server_thread = threading.Thread(target=server.serve_forever) # Exit the server thread when the main thread terminates server_thread.daemon = True server_thread.start() print "Server loop running in thread:", server_thread.name client(ip, port, "Hello World 1") client(ip, port, "Hello World 2") client(ip, port, "Hello World 3") server.shutdown()
Execution result:
$ python ThreadedTCPServer.pyServer loop running in thread: Thread-1Received: Thread-2: Hello World 1Received: Thread-3: Hello World 2Received: Thread-4: Hello World 3