python之select与epoll

select的用法写网络socket的服务端

详解在注释里

import select
import socket
import queue

server = socket.socket()
server.bind(('localhost',9000))
server.listen(1000)

server.setblocking(False)   #设置非阻塞模式
#accept不会堵塞了,没连接会报错

inputs = [server,] #监测的列表
outputs = []    #返回的连接列表
msg_dic = {}    #消息队列字典

while True:
    readable, writeable, exceptional = select.select(inputs, outputs, inputs)
    for r in readable:
        if r is server:  # 如果来的是新连接(server活跃)
            conn, addr = server.accept()
            print('来了个新连接:', addr)
            inputs.append(conn)
            msg_dic[conn] = queue.Queue()
        else:  # 来的是连接
            data = r.recv(1024)
            print('收到', data)
            msg_dic[r].put(data)
            outputs.append(r)

    for w in writeable:  # 要返回给客户端的连接列表
        data_w = msg_dic[w].get()  # 取得消息队列中的元素
        print(data_w)
        w.send(data_w)  # 返回数据
        print('send done')
        outputs.remove(w)  # 确保下次循环的时候writeable,不返回这个已经处理完的连接了

    for e in exceptional:
        if e in outputs:
            outputs.remove(e)  # 如果在返回列表里,就删掉outputs里的e
        inputs.remove(e)  # 删除检测列表里的e
        del msg_dic[e]  # 删除消息队列

然后是客户端:

import socket

HOST = 'localhost'
PORT = 9000

s = socket.socket()
s.connect((HOST,PORT))

while True:
    msg = bytes(input('>>:'), encoding='utf8')
    s.sendall(msg)
    data = s.recv(1024)
    print('收到',data)

python中,Select已经封装好,在python里是selectors模块,里面其实用的是epoll(具体到底是select还是epoll要看操作系统的支持)

 

猜你喜欢

转载自blog.csdn.net/likunkun__/article/details/83112460