IO多路复用
测试代码
import threading
import logging
import selectors
import socket
import time
logging.basicConfig(format='%(asctime)s %(threadName)s %(message)s',level=logging.INFO)
selector = selectors.DefaultSelector()
server = socket.socket()
server.bind(('127.0.0.1',9999))
server.listen()
server.setblocking(False)
def accept(fileobj,mask):
"""mask:事件的掩码,参考子网掩码的使用"""
conn,raddr = fileobj.accept()
conn.send('connected'.encode())
conn.setblocking(False)
key = selector.register(conn,selectors.EVENT_READ,data=recv)
logging.info(key)
def recv(fileobj,mask):
msg = fileobj.recv(1024)
logging.info(msg)
fileobj.send('< {} , {}>'.format(msg,mask).encode())
key = selector.register(server,selectors.EVENT_READ,data=accept)
print(key)
while True:
events = selector.select()
for key,mask in events:
key.data(key.fileobj,mask)
群聊实现
import threading
import logging
import selectors
import socket
logging.basicConfig(format='%(asctime)s %(threadName)s %(message)s',level=logging.INFO)
class ChatServer:
def __init__(self,ip='127.0.0.1',port=9999):
self._laddr = (ip,port)
self._server = socket.socket()
self.selector = selectors.DefaultSelector()
self.event = threading.Event()
def start(self):
self._server.bind(self._laddr)
self._server.listen()
self._server.setblocking(False)
self.selector = selectors.DefaultSelector()
self.selector.register(self._server,selectors.EVENT_READ,data=self.accept)
threading.Thread(target=self.select,name='select',daemon=True).start()
def select(self):
while not self.event.is_set():
events = self.selector.select()
for key,mask in events:
if key.fileobj is self._server:
key.data()
else:
key.data(key.fileobj)
def accept(self):
conn,raddr = self._server.accept()
conn.send('connected'.encode())
conn.setblocking(False)
self.selector.register(conn,selectors.EVENT_READ,data=self.recv)
def recv(self,conn):
msg = conn.recv(1024)
if msg == b'' or msg == b'quit':
self.selector.unregister(conn)
conn.close()
for _,key in self.selector.get_map().items():
print(id(self.accept))
print(id(self.recv))
print(id(key.data))
print(self.recv is key.data)
print(self.recv == key.data)
if key.data == self.recv:
key.fileobj.send(msg)
def stop(self):
self.event.set()
fileobjs = []
for _,key in self.selector.get_map().items():
fileobjs.append(key.fileobj)
for fileobj in fileobjs:
self.selector.unregister(fileobj)
fileobj.close()
self._server.close()
if __name__ == "__main__":
server = ChatServer()
server.start()
while True:
cmd = input('>>>>>')
if cmd == 'quit':
server.stop()
break
print(threading.enumerate())
九九乘法表
print("\n".join('\t'.join(("{}*{}={}".format(j,i,j*i) for j in range(1,i+1))) for i in range(1,10)))