服务器端
1 #!/usr/bin/env python 2 #coding:utf-8 3 4 5 import select 6 import socket 7 import sys 8 import Queue 9 10 11 # Create a TCP/IP socket 12 server = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 13 server.setblocking(0)#设置0就是非阻塞模式,1就是阻塞模式 14 15 # Bind the socket to the port 16 server_address = ('localhost', 10000) 17 print >> sys.stderr, 'starting up on %s port %s' % server_address 18 server.bind(server_address) 19 20 # Listen for incoming connections 21 server.listen(5)#最大允许的连接数是5 22 23 24 # Sockets from which we expect to read 25 inputs = [server] 26 27 # Sockets to which we expect to write 28 outputs = [] 29 30 31 # Outgoing message queues (socket:Queue) 32 message_queues = {} 33 34 while inputs:#死循环 35 36 # Wait for at least one of the sockets to be ready for processing 37 print >>sys.stderr, ' waiting for the next event' 38 readable, writable, exceptional = select.select(inputs, outputs, inputs)#第三个是错误信息,这个select就是要检测是否有就绪的文件描述符 39 40 41 # Handle inputs 42 for s in readable:#找出已经就绪的连接 43 44 if s is server:#如果此时是一个新链接 45 # A "readable" server socket is ready to accept a connection 46 connection, client_address = s.accept() 47 print >> sys.stderr, 'new connection from', client_address 48 connection.setblocking(0) 49 inputs.append(connection) 50 51 # Give the connection a queue for data we want to send 52 message_queues[connection] = Queue.Queue()#每个连接一个q,保证独立不乱 53 54 else:#此时是老连接,开始接收数据 55 data = s.recv(1024) 56 if data: 57 # A readable client socket has data 58 print >> sys.stderr, 'received "%s" from %s' % (data, s.getpeername()) 59 message_queues[s].put(data) 60 # Add output channel for response 61 if s not in outputs: 62 outputs.append(s) 63 else: 64 # Interpret empty result as closed connection 65 print >> sys.stderr, 'closing', client_address, 'after reading no data' 66 # Stop listening for input on the connection 67 if s in outputs: 68 outputs.remove(s) # 既然客户端都断开了,我就不用再给它返回数据了,所以这时候如果这个客户端的连接对象还在outputs列表中,就把它删掉 69 inputs.remove(s) # inputs中也删除掉 70 s.close() # 把这个连接关闭掉 71 72 # Remove message queue 73 del message_queues[s] 74 75 # Handle outputs 76 for s in writable: 77 try: 78 next_msg = message_queues[s].get_nowait() 79 except Queue.Empty: 80 # No messages waiting so stop checking for writability. 81 print >>sys.stderr, 'output queue for', s.getpeername(), 'is empty' 82 outputs.remove(s) 83 else: 84 print >>sys.stderr, 'sending "%s" to %s' % (next_msg, s.getpeername()) 85 s.send(next_msg) 86 87 # Handle "exceptional conditions" 88 for s in exceptional: 89 print >> sys.stderr, 'handling exceptional condition for', s.getpeername() 90 # Stop listening for input on the connection 91 inputs.remove(s) 92 if s in outputs: 93 outputs.remove(s) 94 s.close() 95 96 # Remove message queue 97 del message_queues[s]
客户端
1 #!/usr/bin/env python 2 #coding:utf-8 3 4 import socket 5 import sys 6 7 messages = ['This is the message. ', 8 'It will be sent ', 9 'in parts.', 10 ] 11 server_address = ('localhost', 10000) 12 13 # Create a TCP/IP socket 14 socks = [socket.socket(socket.AF_INET, socket.SOCK_STREAM), 15 socket.socket(socket.AF_INET, socket.SOCK_STREAM), 16 ] 17 18 # Connect the socket to the port where the server is listening 19 print >> sys.stderr, 'connecting to %s port %s' % server_address 20 for s in socks: 21 s.connect(server_address) 22 23 for message in messages: 24 25 # Send messages on both sockets 26 for s in socks: 27 print >> sys.stderr, '%s: sending "%s"' % (s.getsockname(), message) 28 s.send(message) 29 30 # Read responses on both sockets 31 for s in socks: 32 data = s.recv(1024) 33 print >> sys.stderr, '%s: received "%s"' % (s.getsockname(), data) 34 if not data: 35 print >> sys.stderr, 'closing socket', s.getsockname()