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