Asynchronous networks are said to greatly improve the connection speed of network servers. Therefore, I plan to write a topic to learn about asynchronous networks. python has a well-known asynchronous Lib: Twisted. OK. First, write a server segment of the python socket to open three ports: Listen, 10001, 10002. in the krondo example, each server is bound with a port. during the test, three shells must be opened and run separately. this is too troublesome. We use three threads to run these services.
Import optparse import OS import socket import time from threading import Thread import StringIO txt = ''' 1111 2222 3333 4444 ''' def server (listen_socket): while True: buf = StringIO. stringIO (txt) sock, addr = listen_socket.accept () print 'Somebody at % s wants poetry! '% (Addr,) while True: try: line = buf. readline (). strip () if not line: sock. close () break sock. sendall (line) # this is a blocking call print 'send bytes to client: % s' % line # sock. close () handle T socket. error: sock. close () break time. sleep (1) # after the server is connected to the client, the server deliberately sends another word def main (): ports = [10000,100 01, 10002] for port in ports: listen_socket = socket. socket (socket. AF_INET, socket. SOCK_STREAM) listen_socket.setsockopt (socket. SOL_SOCKET, socket. SO_REUSEADDR, 1) addres = (str ('2017. 0.0.1 '), port) listen_socket.bind (addres) listen_socket.listen (5) print "start listen at: % s" % (port,) worker = Thread (target = server, args = [listen_socket]) worker. setDaemon (True) worker. start () if _ name _ = '_ main _': main () while True: time. sleep (0.1) # If you do not run sleep, the CPU will be fully occupied by Python. pass
The following is a client that connects to the server of the three ports without an asynchronous network:
import socket if __name__ == '__main__': ports = [10000, 10001, 10002] for port in ports: address = (str('127.0.0.1'), port) sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.connect(address) poem = '' while True: data = sock.recv(4) if not data: sock.close() break poem += data print poem
The following code reads data using an asynchronous client:
Import datetime, errno, optparse, select, socket def connect (port): "Connect to the given server and return a non-blocking socket. "address = (str ('2017. 0.0.1 '), port) sock = socket. socket (socket. AF_INET, socket. SOCK_STREAM) sock. connect (address) sock. setblocking (0) return sock def format_address (address): host, port = address return '% s: % s' % (host or '127. 0.0.1 ', port) if _ name _ =' _ main _ ': ports = [10000,100 01, 10002] start = datetime. datetime. now () sockets = map (connect, ports) poems = dict. fromkeys (sockets, '') # socket-> accumulated poem # socket-> task numbers sock2task = dict ([(s, I + 1) for I, s in enumerate (sockets)]) sockets = list (sockets) # make a copy while sockets: # Use select to ensure that the readable asynchronous socket can immediately start reading IO # The OS keeps searching for the socket that can be read Currently. If yes, rlist, _, _ = select is returned. select (sockets, [], []) for sock in rlist: data = ''while True: try: new_data = sock. recv (1024) limit T socket. error, e: if e. args [0] = errno. EWOULDBLOCK: break raise else: if not new_data: break else: print new_data data + = new_data task_num = sock2task [sock] if not data: sockets. remove (sock) sock. close () print 'task % d finished '% task_num else: addr_fmt = format_address (sock. getpeername () msg = 'task % d: got % d bytes of poetry from % s' print msg % (task_num, len (data), addr_fmt) poems [sock] + = data elapsed = datetime. datetime. now ()-start print 'got poems in % s' % elapsed
The result takes only 4 seconds to complete the read task. The efficiency is three times that of synchronizing socket. Asynchronous transformation of the client involves two main points:
In synchronous mode, the client creates sockets respectively. in asynchronous mode, the client creates all sockets.
Set socket to asynchronous mode through "sock. setblocking (0.
Returns the readable IO through the select statement of the Unix system.
The core lines are 26 and 29. In particular, the select operation on 29 rows returns the list of sockets to be read.