用select模拟一个socket server成型版2
1.字典队列测试
import queue msg_dic={} msg_dic[1]=queue.Queue() msg_dic[1].put('hello') msg_dic[1].put('bob') print(msg_dic)
运行结果:
C:\abccdxddd\Oldboy\python-3.5.2-embed-amd64\python.exe C:/abccdxddd/Oldboy/Py_Exercise/Day10/eee.py
{1: <queue.Queue object at 0x00801630>}
Process finished with exit code 0
2. 服务器端代码:
import select,socket,queue server=socket.socket() server.bind(('localhost',9000)) server.listen(1024) server.setblocking(False) msg_dic={} #定义一个空字典 inputs=[server,] #inputs=[server,conn,conn2] outputs=[] #outputs=[r1,] while True: readable,writeable,exceptional=select.select(inputs,outputs,inputs) print(readable,writeable,exceptional) for r in readable: if r is server: conn,addr=server.accept() print('来了个新链接',addr) inputs.append(conn) msg_dic[conn]=queue.Queue() #初始化一个队列,后面存要返回给客户端的数据。键值key:value=conn(键):queue.Queue(值) else: #r is conn/conn2... data=r.recv(1024) print('收到数据',data) msg_dic[r].put(data) #把要发的数据存在字典里面,等下次循环的时候发。 outputs.append(r) #放入返回的链接队列里.往output里面放什么,那么下次循环就出什么。往output里面放的是conn2,那么出的就是conn2 #r.send(data) for w in writeable: #要返回给客户端的链接列表,writeable里面存放的是r (conn,conn2) data_to_client=msg_dic[w].get() w.send(data_to_client) #返回给客户端源数据。这样收和发就分开了。 outputs.remove(w) #确保下次循环的时候writeable不返回这个已经处理完的链接了。 for e in exceptional: #这个链接已经断开了,出问题了,我就不再检测它了。 if e in outputs: outputs.remove(e) inputs.remove(e) del msg_dic[e]
客户端代码:
import socket s=socket.socket() s.connect(('localhost',9000)) while True: msg=bytes(input(">>:"),encoding='utf8') s.sendall(msg) data=s.recv(1024) print('Received',data) s.close()