利用IO多路复用,使用linux下的EpollSelector实现并发服务器
1 import socket 2 import selectors # IO多路复用选择器的模块 3 4 # 实例化一个和epoll通信的选择器 5 epoll_selector = selectors.EpollSelector() # 如果是非linux系统: .DefaultSelector() 6 server = socket.socket() 7 server.bind(('', 9980)) 8 server.listen(1000) 9 10 def recv(conn): 11 '''接收数据''' 12 recv_data = conn.recv(1024) 13 if recv_data: 14 print(recv_data.decode()) 15 conn.send(recv_data) 16 else: 17 epoll_selector.unregister(conn) # 关闭epoll监控 18 conn.close() 19 20 def accept(server1): 21 '''建立连接''' 22 conn, addr = server1.accept() 23 epoll_selector.register(conn, selectors.EVENT_READ, recv) 24 25 # 注册事件 26 epoll_selector.register(server, selectors.EVENT_READ, accept) 27 28 while True: 29 '''显示查询的好的事件''' 30 events = epoll_selector.select() 31 # print(events) 32 ''' 33 [(SelectorKey(fileobj=<socket.socket fd=4, 34 family=AddressFamily.AF_INET, 35 type=SocketKind.SOCK_STREAM, 36 proto=0, 37 laddr=('0.0.0.0', 9989)>, 38 fd=4, 39 events=1, 40 data=<function accept at 0xb71dc92c>), # 一个函数地址 41 42 43 1)] 44 列表里面两个元素,一个是函数SelectorKey(), 45 括号里面是一个套接字fileobj,一个fd,一个events,一个data 46 ''' 47 for key, mask in events: 48 callable = key.data # 取出回调函数 49 sock = key.fileobj # 取出套接字 50 callable(sock)