用select实现socket的IO多路复用

这个写的是服务端,客户端比较简单,就不写啦!

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]

  

原文地址:https://www.cnblogs.com/575dsj/p/7760343.html