This article mainly introduces the use of the select module in Python to implement non-blocking IO. This article uses a simple chat room program to explain the use of the select module in Python, for more information, see Socket. The original meaning is "hole" or "Socket ". As the process communication mechanism of bsd unix, take the latter meaning. It is also called "socket". it is used to describe the IP address and port and is a communication chain handle. Hosts on the Internet generally run multiple service software and provide several services at the same time. Each service opens a Socket and binds it to a port. different ports correspond to different services. Socket is like a porous Socket, just as it was originally intended. A host is like a room with various sockets. Each socket has a serial number. some sockets provide 220 v ac, some provide 110 v ac, and some provide cable TV programs. The customer software inserts the plug into a socket with different numbers to obtain different services. -Baidu Encyclopedia
Socket is so important that almost all network programming is now used. it originated from Unix, and one of the basic philosophies of Unix/Linux is "everything is a file", which can be opened, read, and written, in disabled mode. However, network services often target a large number of customers, such as the web. for such services, it is necessary to ensure that requests can be processed in parallel and service stability. However, traditional sockets are lacking in processing concurrency. with the help of the select module, non-blocking IO is better.
The select module in Python accepts four parameters in the form of a list: readable file objects to be monitored, writable file objects, abnormal file objects and timeout settings, when the monitored object changes, select returns the list of objects that change. The following describes how to use select to implement a simple chat room:
#! /Usr/bin/env python # *-* coding: UTF-8 *-* import socketimport selectimport sysimport signalclass ChatServer (): def _ init _ (self, host, port, timeout = 10, backlog = 5): # record the number of connected clients self. clients = 0 # store the dictionary self corresponding to the connected client socket and address. clientmap = {}# store the connected client socket self. outputs = [] # create socket self. server = socket. socket (socket. AF_INET, socket. SOCK_STREAM) self. server. setsockopt (socket. SOL_SOCKET, socket. SO_REUSEADDR, 1) se Lf. server. bind (host, port) self. server. listen (backlog) # Add signal processing signal. signal (signal. SIGINT, self. sighandler) def sighandler (self): sys. stdout. write ("Shutdown Server ...... \ n ") # send link information to connected clients, and disable socket for output in self. outputs: output. send ("Shutdown Server") output. close () # close listen self. server. close () sys. stdout. flush () # main function, used to start the server def run (self): # the readable object to be monitored, inputs = [self. server] runing = True # Add Add listener main loop while runing: try: readable, writeable, predictional = select. select (inputs, self. outputs, []) # This is blocked by the select module. only when the three parameters of the listener change will the select return limit T select. error, e: break # When the returned readable contains information about the local socket, it indicates that a client is requesting to connect to if self. server in readable: # accept client connection request client, addr = self. server. accept () sys. stdout. write ("New Connection from % s \ n" % str (addr) sys. stdout. flush () # update client connection status on the server #1, quantity plus 1 #2, self. add a column to outputs #3, self. add a pair of #4 to clientmap and add readable monitoring self to the input. clients + = 1 self. outputs. append (client) self. clientmap [client] = addr inputs. append (client) # readable contains the added client socket and is readable # Description 1. the client sends data or 2. the client requests to disable elif len (readable )! = 0: #1. fetch the socket csock = readable [0] #2 in this list. Based on this socket, remove the client address from the clientmap stored in advance, port details host, port = self. clientmap [csock] #3. fetch data, accept or close the request, and process it # note that this operation is blocked, but since the data is cached locally, so the speed will be very fast. try: data = csock. recv (1, 1024 ). strip () for cs in self. outputs: if cs! = Csock: cs. send ("% s \ n" % data) failed t socket. error, e: self. clients-= 1 inputs. remove (csock) self. outputs. remove (csock) del self. clientmap [csock] # print self. outputs self. server. close () if _ name _ = "_ main _": chat = ChatServer ("", 8008) chat. run ()
Run this script and use any client, such as telnet or netcat, to connect to port 8008. then, multiple clients can communicate with each other.
In fact, the select module itself is blocked. when the socket to be monitored changes, the select module returns the result. The following program continues to be executed. The program processes various situations based on the select return value.