此模块允许高级和高效的I / O多路复用,建立在选择模块基元上。 鼓励用户使用此模块,除非他们需要精确控制所使用的操作系统级原语。
selectors的DefaultSelector会自动选择所在平台最高效的实现,顺序是:epoll,poll,select。
注意:
selectors是python3.4才新增的
一个简单的selectors客户端代码示例:
import selectors
import socket
ip_port = ("127.0.0.1", 8079)
back_log = 5
buffer_size = 1024
class SelectServer:
def __init__(self):
# 根据电脑系统默认优先选择epoll,poll,select顺序
self.sel = selectors.DefaultSelector()
self.creta_socket()
self.handle()
def creta_socket(self):
sel_server = socket.socket()
sel_server.bind(ip_port)
sel_server.listen(back_log)
# 禁止IO阻塞
sel_server.setblocking(False)
self.sel.register(sel_server, selectors.EVENT_READ, self.accept)
print("服务端已开启,等待用户连接")
def handle(self):
while True:
events = self.sel.select()
for key, mask in events:
print("key", key, "\nmask", mask)
callback = key.data # 函数内存
callback(key.fileobj, mask)
def accept(self, sock, mask):
# 准备连接
conn, addr = sock.accept()
print("accept ", conn, "from", addr)
conn.setblocking(False)
self.sel.register(conn, self.read)
def read(self, mask):
try:
# 接受数据
data = conn.recv(buffer_size)
if data:
print(repr(data), "to", conn)
conn.sendall(data)
else:
print("closing ", conn)
self.sel.unregister(conn)
conn.close()
except ConnectionResetError:
self.sel.unregister(conn)
conn.close()
if __name__ == '__main__':
SelectServer()
seletors客户端代码示例:
import socket
ip_port = ("127.0.0.1", 8079)
buffer_size = 1024
class SelectClient:
def __init__(self):
self.create_socket()
self.run()
def create_socket(self):
self.s_client = socket.socket()
self.s_client.connect(ip_port)
def run(self):
while True:
data = input(">>>")
self.s_client.send(bytes(data, "utf8"))
print(str(self.s_client.recv(buffer_size),"utf-8"))
if __name__ == '__main__':
SelectClient()