这个写的是服务端,客户端比较简单,就不写啦!
import socket
import select
import queue
server=socket.socket()
server.bind(('localhost',9000))
# 对于IO多路复用需要设置为非阻塞模式
server.setblocking(False)
server.listen(1024)
msg_dic={}
inputs=[server]
outputs=[]
# select需要循环监听,所以这里添加死循环
while True:
in_list,out_list,except_list=select.select(inputs,outputs,inputs)
for i in in_list:
if i is server:#有新链接进来
conn,addr=i.accept()
inputs.append(conn)
# 给每一个链接赋值成一个队列
msg_dic[conn]=queue.Queue()
# 其实select监测到的返回值不应该是具体的某一个conn,但是python的select做了封装,所以可以直接使用
else:#有消息需要接收
data=i.recv(1024)
print(data)
#以下代码是为了把要返回的数据放入某一个链接的队列里
msg_dic[i].put(data)
#放完数据还要把该链接放入outputs队列,以便在下次select循环监听时,发送数据
outputs.append(i)
# 这里在每次监听的最后返回上次conn需要返回的数据,其实可以直接返回数据的,这里这样写是为了装个逼
for j in out_list:
j.send(msg_dic[j].get())
# 发送完数据就从需要返回消息的队列里清除该链接
outputs.remove(j)
for e in except_list:
# 链接出现异常,就不再返回数据,select也不再循环监听,消息队列也需要抹去这条数据
if e in outputs:
outputs.remove(e)
inputs.remove(e)
del msg_dic[e]