参考源
- cai128118*
https://www.cnblogs.com/cainingning/p/9556642.html - 老男孩教育林海峰(Egon)老师
selectors模块
介绍
selectors模块帮我们选择当前操作系统平台下最合适的IO多路复用机制
- 有epoll就用epoll
- 有poll就用poll
- 有select就用select
导入
selectors
模块是一个内置模块, 直接导入即可.
import selectors
实现
Server端
#!/usr/bin/python3
# -*- coding: utf-8 -*-
"""IO多路复用之selectors模块
selectors模块帮我们选择当前操作系统平台下最合适的IO多路复用机制
有epoll就用epoll
有poll就用poll
有select就用select
Server端
"""
import selectors
import socket
def to_accept(sock, mask):
conn, addr = sock.accept()
conn.setblocking(False)
sel.register(fileobj=conn, events=selectors.EVENT_WRITE, data=to_read)
def to_read(conn, mask):
try:
recvs = conn.recv(1024)
if not recvs:
sel.unregister(fileobj=conn)
conn.close()
return
print(recvs.decode(encoding='utf-8'))
sel.unregister(fileobj=conn)
wdict[conn] = b'%s' % (recvs, )
sel.register(fileobj=conn, events=selectors.EVENT_WRITE, data=to_write)
except ConnectionResetError:
sel.unregister(fileobj=conn)
conn.close()
return
def to_write(conn, mask):
# print(mask) # EVENT_READ 值为1, EVENT_WRITE 值为2
conn.sendall(wdict.get(conn))
wdict.pop(conn)
sel.unregister(fileobj=conn)
sel.register(fileobj=conn, events=selectors.EVENT_READ, data=to_read)
sk = socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM)
sk.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sk.bind(('', 8080))
sk.listen(32)
sk.setblocking(False)
sel = selectors.DefaultSelector()
sel.register(fileobj=sk, events=selectors.EVENT_READ, data=to_accept)
wdict = dict()
while 1:
events = sel.select(timeout=None)
for sel_obj, mask in events:
callback = sel_obj.data
callback(sel_obj.fileobj, mask)
Client端
#!/usr/bin/python3
# -*- coding: utf-8 -*-
"""IO多路复用之selectors模块
Client端
"""
import socket
import threading
def my_client():
sk = socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM)
sk.connect(('localhost', 8080))
while 1:
sk.send(b'hi')
msg = sk.recv(1024)
print(msg)
for i in range(10):
threading.Thread(target=my_client).start()