利用IO多路复用,使用linux下的EpollSelector实现并发服务器

时间:2021-11-25 17:55:09
 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)