# I/O模型
# block I/O 阻塞IO 类型于socket中的例子
# noblocking I/O 非阻塞IO 缺点:发了太多的系统调用,不能及时处理数据
server.py
import time, socket sk = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sk.bind(('127.0.0.1', 8080)) sk.listen(5) sk.setblocking(False) # 设置阻塞为False print('waiting client connecting...') while True: try: conn, addr = sk.accept() # 进程主动轮询 print('+++', addr) client_message = conn.recv(1024) print(str(client_message, 'utf-8')) conn.close() except Exception as e: # 当没有客户端连接时,执行下面代码 print(e) time.sleep(4)
client.py
import socket, time sk = socket.socket(socket.AF_INET, socket.SOCK_STREAM) while True: sk.connect(('127.0.0.1', 8080)) print('hello') sk.sendall(bytes('hello', 'utf-8')) time.sleep(2) break
# I/O multiplexing IO多路复用:利用IO空闲的时间来处理并发(select poll epoll 效率从低到高)
# 在windows下只有select (跨平台,最大连接数为1024), linux下select poll epoll都有
server.py
import socket import select sk = socket.socket() sk.bind(('127.0.0.1', 8080)) sk.listen(5) inputs = [sk, ] while True: r, w, e = select.select(inputs, [], [], 5) # 参数为输入列表(监听了sk对象), 输出列表, 错误列表, 每隔几秒钟进行监听 print(len(r)) for obj in r: if obj == sk: # 判断接收的是sk还是conn,如果是sk,就建立连接 conn, add = obj.accept() print(conn) inputs.append(conn) # 将conn加入到输入列表中 else: # 如果是conn 就收发信息 data_byte = obj.recv(1024) print(str(data_byte, 'utf-8')) inp = input('回答%s号客户>>>' % inputs.index(obj)) obj.sendall(bytes(inp, 'utf-8')) print('>>>>', r)
client.py
import socket sk = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sk.connect(('127.0.0.1', 8080)) while True: inp = input('>>').strip() sk.sendall(inp.encode('utf-8')) data = sk.recv(1024) print(data.decode('utf-8'))
# Asynchronous I/O 异步IO 所有IO模型中效率最好的一个,全程无阻塞