import selectors
import socket
import threading
import myutils
def recv(conn:socket.socket):
data = conn.recv(1024).strip().decode()
print(data)
msg = 'Your msg = {}\n'.format(data)
conn.send(msg.encode())
def accept(sock:socket.socket):
conn,client = sock.accept()
conn.setblocking(False)
selector.register(conn,selectors.EVENT_READ,recv)
#创建监听socket对象
sock = socket.socket()
ip = '127.0.0.1'
port = 9990
addr = (ip,port)
sock.bind(addr)
sock.listen()
sock.setblocking(False)
#平台自适应
selector = selectors.DefaultSelector()
key = selector.register(sock,selectors.EVENT_READ, accept)
#SelectorKey(fileobj=如下, fd=4, events=1, data=<function accept at 0x7f5ad883f268>)
#fileobj=<socket.socket fd=4, family=AddressFamily.AF_INET, type=2049, proto=0, laddr=('127.0.0.1', 9990)>
print(key)#四元组
myutils.showthreads()
e = threading.Event()
while not e.is_set():
events = selector.select()
if events:
print('`````````',events)#列表,列表元素为二元组,二元组的元素由一个四元组和1-3数字组成
for key,mask in events:
print('=========',key,mask)
callback = key.data
callback(key.fileobj)
额外自定义模块myutils的代码如下:
import threading,logging
logging.basicConfig(level=logging.INFO)
e = threading.Event()
def showthreads():
def _showthread():
while not e.wait(5):
logging.info(threading.enumerate())
threading.Thread(target=_showthread,daemon=True).start()
运行结果:
SelectorKey(fileobj=<socket.socket fd=3, family=AddressFamily.AF_INET, type=2049, proto=0, laddr=('127.0.0.1', 9990)>, fd=3, events=1, data=<function accept at 0x7f5801bc09d8>)
`````````[(SelectorKey(fileobj=<socket.socket fd=3, family=AddressFamily.AF_INET, type=2049, proto=0, laddr=('127.0.0.1', 9990)>, fd=3, events=1, data=<function accept at 0x7f5801bc09d8>), 1)]
========= SelectorKey(fileobj=<socket.socket fd=3, family=AddressFamily.AF_INET, type=2049, proto=0, laddr=('127.0.0.1', 9990)>, fd=3, events=1, data=<function accept at 0x7f5801bc09d8>) 1
INFO:root:[<_MainThread(MainThread, started 140015987357440)>, <Thread(Thread-1, started daemon 140015962216192)>]
`````````[(SelectorKey(fileobj=<socket.socket fd=5, family=AddressFamily.AF_INET, type=2049, proto=0, laddr=('127.0.0.1', 9990), raddr=('127.0.0.1', 53582)>, fd=5, events=1, data=<function recv at 0x7f5803191268>), 1)]
========= SelectorKey(fileobj=<socket.socket fd=5, family=AddressFamily.AF_INET, type=2049, proto=0, laddr=('127.0.0.1', 9990), raddr=('127.0.0.1', 53582)>, fd=5, events=1, data=<function recv at 0x7f5803191268>) 1
hello
INFO:root:[<_MainThread(MainThread, started 140015987357440)>, <Thread(Thread-1, started daemon 140015962216192)>]
改进:
import selectors
import socket
import threading
# 平台自适应
selector = selectors.DefaultSelector()
def recv(conn: socket.socket,mask):
data = conn.recv(1024).strip().decode()
print(data)
msg = 'Your msg = {}\n'.format(data)
conn.send(msg.encode())
def accept(sock: socket.socket,mask):
conn, client = sock.accept()
conn.setblocking(False)
selector.register(conn, selectors.EVENT_READ, recv)
# 创建监听socket对象
sock = socket.socket()
ip = '127.0.0.1'
port = 9990
addr = (ip, port)
sock.bind(addr)
sock.listen()
sock.setblocking(False)
key = selector.register(sock, selectors.EVENT_READ, accept)
# SelectorKey(fileobj=如下, fd=4, events=1, data=<function accept at 0x7f5ad883f268>)
# fileobj=<socket.socket fd=4, family=AddressFamily.AF_INET, type=2049, proto=0, laddr=('127.0.0.1', 9990)>
print(key) # 四元组
e = threading.Event()
def work(event:threading.Event):
while not e.is_set():
events = selector.select()
if events:
print('1,event = {}'.format(events))
for key,mask in events:
callback = key.data
callback(key.fileobj,mask)
threading.Thread(target=work,name='work',args=(e,)).start()
while not e.is_set():
cmd = input('>>>>')
if cmd.strip() == 'quit':
e.set()
fobjs = []
print(2,selector.get_map().items())
for fobj,key in selector.get_map().items():
print(3,fobj,key)
print(4,key.fileobj)
key.fileobj.close()
fobjs.append(fobj)
for x in fobjs: #实际x为文件描述符
selector.unregister(x)
selector.close()
运行结果:
SelectorKey(fileobj=<socket.socket fd=4, family=AddressFamily.AF_INET, type=2049, proto=0, laddr=('127.0.0.1', 9990)>, fd=4, events=1, data=<function accept at 0x7f565d170b70>)
>>>>1,event = [(SelectorKey(fileobj=<socket.socket fd=4, family=AddressFamily.AF_INET, type=2049, proto=0, laddr=('127.0.0.1', 9990)>, fd=4, events=1, data=<function accept at 0x7f565d170b70>), 1)]
1,event = [(SelectorKey(fileobj=<socket.socket fd=5, family=AddressFamily.AF_INET, type=2049, proto=0, laddr=('127.0.0.1', 9990), raddr=('127.0.0.1', 54248)>, fd=5, events=1, data=<function recv at 0x7f565e6c7268>), 1)]
hello
quit
2 ItemsView(<selectors._SelectorMapping object at 0x7f565e6d8c18>)
3 4 SelectorKey(fileobj=<socket.socket fd=4, family=AddressFamily.AF_INET, type=2049, proto=0, laddr=('127.0.0.1', 9990)>, fd=4, events=1, data=<function accept at 0x7f565d170b70>)
4 <socket.socket fd=4, family=AddressFamily.AF_INET, type=2049, proto=0, laddr=('127.0.0.1', 9990)>
3 5 SelectorKey(fileobj=<socket.socket fd=5, family=AddressFamily.AF_INET, type=2049, proto=0, laddr=('127.0.0.1', 9990), raddr=('127.0.0.1', 54248)>, fd=5, events=1, data=<function recv at 0x7f565e6c7268>)
4 <socket.socket fd=5, family=AddressFamily.AF_INET, type=2049, proto=0, laddr=('127.0.0.1', 9990), raddr=('127.0.0.1', 54248)>