Python网络编程笔记二
使用select模块实现IO多路复用服务端
1 import socket 2 import select 3 #windows上只支持select.select,不支持poll epoll 4 5 HOST = "127.0.0.1" 6 PORT = 9999 7 BUFFSIZE = 1024 8 ADDR = (HOST, PORT) 9 #创建服务器端监听套接字 10 tcpSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 11 tcpSocket.bind(ADDR) 12 tcpSocket.listen(5) 13 tcpSocket.setblocking(0) 14 15 16 #监听读事件 17 inputs = [tcpSocket] 18 #监听写事件 19 outputs = [] 20 #监听异常事件 21 exceptions = [] 22 23 messageDict = {} 24 25 while True: 26 #每当有客户端连接时,返回的r_list中包含监听的服务器套接字tcpSocket 27 #w_list中始终与outputs相同 28 r_list, w_list, e_list = select.select(inputs, outputs, exceptions, 1) 29 print(len(inputs)) 30 for r in r_list: 31 if r == tcpSocket: 32 request, addr = r.accept() 33 request.setblocking(0) 34 #将客户端套接字加入到监听列表中,接下来每当客户端发送数据过来,r_list中即可包含该套接字 35 inputs.append(request) 36 messageDict[request] = [] 37 #如果套接字不等于tcpSocket,说明是客户端发送数据 38 else: 39 try: 40 dataBytes = r.recv(1024) 41 #说明客户端断开连接 42 #ConnectionResetError 43 except Exception as e: 44 #将客户端套接字移除出监听列表 45 inputs.remove(r) 46 del messageDict[r] 47 r.close() 48 else: 49 dataStr = str(dataBytes, encoding="utf-8") 50 messageDict[r].append(dataStr) 51 # print("接收到来自", r.getpeername(), " : ", dataStr) 52 # r.sendall(bytes("已经收到您发送的" + dataStr, encoding="utf-8")) 53 #添加到outputs,下次再循环时w_list中包含数据 54 outputs.append(r) 55 56 for w in w_list: 57 messageList = messageDict[w] 58 recvData = messageList[0] 59 del messageList[0] 60 print("接收到来自", w.getpeername(), " : ", recvData) 61 w.sendall(bytes("已经收到您发送的" + recvData, encoding="utf-8")) 62 outputs.remove(w) 63 tcpSocket.close()