非阻塞套接字和IO模型

非阻塞套接字:

  防止进入阻塞状态,程序停滞。如recv、accept、input都会阻塞。 

  socket.socket()生成一个套接字用于监听;server.accept()生成一个套接字用于收发信息;两者都要设置非阻塞

 1 import socket
 2 
 3 server = socket.socket()
 4 server.setblocking(False)  # 将套接字设置为非阻塞
 5 server.bind(('', 9009))
 6 server.listen(1000)
 7 print('开始监听')
 8 client_list = []
 9 while True:
10     try:
11         conn = server.accept()
12         conn[0].setblocking(False)
13     except BlockingIOError:
14         pass
15     else:
16         print('客户端{},连接成功'.format(conn[1]))
17         client_list.append(conn[0])
18     client = client_list
19     for client_socket in client_list:
20         try:
21             data = client_socket.recv(1024)
22         except BlockingIOError:
23             pass
24         else:
25             if len(data) > 0:
26                 print(data)
27             else:
28                 client_socket.close()
29                 client.remove(client_socket)
30     client_list = client

 

 IO模型:

 1 import selectors
 2 import socket
 3 import time
 4 
 5 server = socket.socket()
 6 sel = selectors.DefaultSelector()
 7 server.bind(('', 56563))
 8 server.listen(5)
 9 
10 
11 # 注册事件
12 def acc_read(conn):
13     try:
14         data = conn.recv(1024)
15     except ConnectionResetError:
16         sel.unregister(conn)
17         print('服务端正在关闭')
18         conn.close()
19     else:
20         conn.send(data)
21         print('信息:{},正在发送'.format(data))
22 
23 
24 def acc(servers):
25     conn, address = servers.accept()
26     print('客户端{},连接成功'.format(address))
27     sel.register(conn, selectors.EVENT_READ, acc_read)
28 
29 
30 sel.register(server, selectors.EVENT_READ, acc)
31 
32 while True:
33     events = sel.select()
34     for key, mask in events:
35         callback = key.data
36         callback(key.fileobj)
37         time.sleep(3)