通过select进行io多路复用
io多路复用的原理和阻塞io相似,只是select可以同时监听多个连接,并且对连接的变化做出响应。
1.select
即使是tcp也可以同时连接多个客户端
from socket import * import select s1=socket(AF_INET,SOCK_STREAM) s1.bind(('127.0.0.1',8080)) s1.listen(5) s1.setblocking(False) while 1: r,w,e=select.select([s1,],[],[])#r就是select监听的列表,可以是多个 for i in r: conn,addr=i.accept() conn.send('good'.encode('utf8')) data=conn.recv(1024) print(data.decode('utf-8'))
from socket import * c1=socket(AF_INET,SOCK_STREAM) c1.connect(('127.0.0.1',8080)) while 1: c1.send('hello'.encode('utf8')) data=c1.recv(1024) print(data.decode('utf-8'))
2.selector
import selectors from socket import * def fun_s2(s2,mask): conn,addr=s2.accept() conn.setblocking(False) s1.register(conn,selectors.EVENT_READ,fun_conn) def fun_conn(conn,mask): data=conn.recv(1024) print(data.decode('utf-8')) s1=selectors.DefaultSelector() s2=socket(AF_INET,SOCK_STREAM) s2.bind(('127.0.0.1',8080)) s2.listen(5) s2.setblocking(False) s1.register(s2,selectors.EVENT_READ,fun_s2) while 1: l=s1.select() for i,mask in l: callback=i.data callback(i.fileobj,mask)
from socket import * c1=socket(AF_INET,SOCK_STREAM) c1.connect(('127.0.0.1',8080)) while 1: c1.send(input().encode('utf8')) data=c1.recv(1024) print(data.decode('utf-8'))
其实就是写了两个函数,一个sock调用,一个conn调用,一个完成绑定,一个完成收发操作。