非阻塞套接字和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)