#coding=utf-8 #IO多路复用 #必须在非阻塞状态下才能使用socket的多路复用 import select import socket import sys import Queue sever = socket.socket() sever.bind((‘localhost‘,9000)) sever.listen(1000) sever.setblocking(False) #设置非阻塞模式 inputs = [sever] outputs = [] msg_dict = dict() while True: readable,writeable,exceptionable = select.select(inputs,outputs,inputs) #检测到的链接放到inputs里面 print readable,writeable,exceptionable for r in readable: if r is sever: con,addr=sever.accept() inputs.append(con)#因为新建立的链接没有发数据,因为是非阻塞,所以会出错,因此要把con加入select的监测列表 print ‘有新的连接接入‘,con,addr msg_dict[con] = Queue.Queue() else: try: data = r.recv(1024) print ‘收到数据:‘,data except socket.error: print ‘客户端断开了:‘, inputs.remove(r) continue r.send(data) msg_dict[r].put(data) outputs.append(r)#放入返回的链接 for w in writeable: #要返回给客户端的了链接列表 data1 = msg_dict[w].get() w.send(data1) #返回给客户端数据 outputs.remove(w) #确保斜刺循环的时候不返回已经处理的列表 # sever.accept() for e in exceptionable: if e in outputs: outputs.remove(e) inputs.remove() del msg_dict[e] #selector模块 import selectors import socket sel = selectors.DefaultSelector() def accept(sock, mask): conn, addr = sock.accept() # Should be ready print(‘accepted‘, conn, ‘from‘, addr,mask) conn.setblocking(False) sel.register(conn, selectors.EVENT_READ, read) #新连接注册read回调函数,一调用read说明conn有数据接受了 def read(conn, mask): data = conn.recv(1024) # Should be ready if data: print(‘echoing‘, repr(data), ‘to‘, conn) #repr?? conn.send(data) # Hope it won‘t block else: print(‘closing‘, conn) sel.unregister(conn) conn.close() sock = socket.socket() sock.bind((‘localhost‘, 9999)) sock.listen(100) sock.setblocking(False) sel.register(sock, selectors.EVENT_READ, accept) #让select监听。回调函数accept。有活动就调此函数 while True: events = sel.select() #默认阻塞,有活动连接就返回活动的连接列表 for key, mask in events: callback = key.data #accept callback(key.fileobj, mask) #key.fileobj= 文件句柄