OK, first write a Python socket server segment, to open three ports: 10000,10001,10002.krondo example is each server bound to a port, the test need to open 3 shell, respectively, run. It's too much trouble. The services are run with three thread respectively.
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.acc EPT () print ' Somebody at%s wants poetry! '% (addr,) while True:try:line = Buf.readline (). Stri P () if not line:sock.close () break Sock.sendall (line) # This is a blocking CA ll print ' Send bytes to client:%s '% line #sock. Close () except socket.error:sock.cl OSE () Break Time.sleep (1) #server和client连接后, the server intentionally waits one second after each word to send another word def main (): ports = [1 0000, 10001, 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 (' 127.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]) work Er.setdaemon (True) Worker.start () if __name__ = = ' __main__ ': Main () while True:time.sleep (0.1) #如果不sleep的 CPU will be fully occupied by Python.
Here is a client that does not use an asynchronous network to connect to this three-port server:
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
The following is read with the async client, the code is as follows:
Import datetime, errno, Optparse, select, Socket def connect (port): "" Connect to the given server and return a NON-BL ocking socket. "" " Address = (str (' 127.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 = add ress return '%s:%s '% (host or ' 127.0.0.1 ', port) if __name__ = = ' __main__ ': ports = [10000, 10001, 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-enumerate (sockets)]) sockets = List (so Ckets) # Make a copy while sockets: #运用select来确保那些可读取的异步socket可以立即开始读取IO #OS不停的搜索目前可以read的socket, return rlist Rlist, _, _ = Select.select (sockets, [], []) for sock in rlist:data = "while true:try: New_data = Sock.recv (1024x768) excePT 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:sock Ets.remove (sock) sock.close () print ' Task%d finished '% task_num else:addr_fmt = Format_ad Dress (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 is a read task that takes only 4 seconds to complete. The efficiency is three times times that of the sync socket just now. There are two main points to the asynchronous transformation of the client:
In synchronous mode, the client creates the socket separately, and in asynchronous mode, all of the sockets are created.
Set the socket to asynchronous mode with "sock.setblocking (0)".
The select two of the UNIX system return to read IO
The core is 26 rows and 29 rows. In particular, the 29-row Select operation returns the list of sockets to be read.