This article we look at from the socket programming example
Python Asynchronous FrameworkHow it works, you need to understand the simple socket programming and the I/O multiplexing mechanism provided by Linux.
Python Asynchronous FrameworkIt is also based on the I/O multiplexing mechanism provided at the bottom of the operating system, such as Select/poll/epoll, which can be used under Linux. Let's look at a simple Python socket server example where Python code uses PYTHON3 to make sure you can use the selectors module.
An instance
Import sockethost = ' localhost ' # the remote Hostport = 8888 # arbitrary non-privileged portwith socket.socket (socket. Af_inet, Socket. SOCK_STREAM) as S: s.setsockopt (socket. Sol_socket, SOCKET. SO_REUSEADDR, 1) S.bind ((HOST, PORT)) S.listen () while True: conn, addr = s.accept () print (' Connected by ', addr) with conn: while 1: data = CONN.RECV (1024x768) if not data: break Conn.sendall (data)
Below we tested it with a Golang TCP client:
Package Mainimport ( "FMT" "NET" " os" " sync") Func sendMessage (msg string) error { conn, err: = Net. Dial ("TCP", "localhost:8888") if err! = Nil { return FMT. Errorf ("Error:%v", err) } defer conn. Close () _, Err = conn. Write ([]byte ("Hello")) if err! = Nil { return FMT. Errorf ("Error:%v", err) } Reply: = make ([]byte, 1024x768) _, Err = conn. Read (Reply) if err! = Nil { println ("Write to Server failed:", err. Error ()) OS. Exit (1) } println ("Reply from server=", string (Reply)) return Nil}func main () { var wg sync. Waitgroup nbgoroutines: = WG. ADD (Nbgoroutines) for k: = 0; k < nbgoroutines; k++ { go func () { err: = SendMessage ("Hello") if ER R! = Nil { FMT. Printf ("Fail:%v\n", err) } WG. Done () } () } WG. Wait ()}
Run it with go to see the output.
Next we use the Selectros provided by Python3 to transform it, which encapsulates the I/O multiplexing mechanism provided by the operating system, such as the use of Epoll on Linux. Through the I/O multiplexing mechanism, we can listen to read and write events for multiple file descriptors and register callback functions for better concurrency performance. First look at the example of Python3 's selectors document
Import Selectorsimport Socketsel = selectors. Defaultselector () def accept (sock, mask): conn, addr = Sock.accept () # should is ready print (' Accepted ', Conn, ' from ', addr) conn.setblocking (False) Sel.register (conn, selectors. Event_read, read) def READ (Conn, mask): data = CONN.RECV (+) # should is ready if data: print (' Echoing ', repr (data), ' to ', conn) conn.send (data) # Hope It won ' t block else: print (' closing ', conn ) Sel.unregister (conn) conn.close () sock = Socket.socket () sock.bind ((' localhost ', 1234)) Sock.listen (100) Sock.setblocking (False) sel.register (sock, selectors. Event_read, accept) while True: # This is actually the event loop that is usually referred to in the asynchronous framework events = Sel.select () for Key, the mask in event S: callback = Key.data callback (Key.fileobj, mask)
Let's run the next TCP echo server that uses the seelctors I/O multiplexing mechanism to see the output.
We're almost there, and we're going to run the go-write TCP client to test the results.
In the back tutorial we will use Python's coroutine instead of the callback function to transform the example so that we can use async/await to run it.