多路复用--day37
"""
----多路复用----
指的是
多个连接在复用一个线程
反过来说 一个线程处理多个连接
提高了单线程处理能
多路复用提升的 单线程处理网络IO的效率
协程提升的是 单线程处理所有IO的效率
"""
# 多路复用
import socket import select server = socket.socket() server.bind(("127.0.0.1",21211)) server.listen() # 将服务端设置为非阻塞 # server.setblocking(False) # select 是帮我们监控连接 # 需要给它传两个列表 一个是检测是否可读(是否可以执行recv) 一个是检测是否可写(是否可执行send) rlist = [server,] wlist = [] # 默认select是阻塞的 会直到有其中一个或几个需要被处理 # 存储要发送的数据 msg = {} # 返回值 # 1.可读的连接(可以执行recv) # 2.可写的连接(可以执行send) while True: readable_list,writeable_list,_ = select.select(rlist,wlist,[]) # 接下来就是要处理这些可读可写列表 print(readable_list) # 处理可读列表 for c in readable_list: if c == server: # 说明当需要被处理的是服务器 client,addr = c.accept() # 把客户端也交给select来检测 rlist.append(client) else: print("客户端可以recv啦!") data = c.recv(1024) print(data.decode("utf-8")) # 给客户端返回数据 # c.send(data.upper()) wlist.append(c) # 将客户端也交给select检测是否可写 msg[c] = data print(writeable_list) print(msg) # 处理可写列表 for w in writeable_list: w.send(msg[w].upper()) # 将已经发送完成的连接从 检测列表删除 wlist.remove(w)
# ----多路复用实现原理----
# ----多路复用实现原理---- import socket server = socket.socket() server.bind(("127.0.0.1",21211)) server.listen() server.setblocking(False) # all clients clients = [] while True: try: client,addr = server.accept() clients.append(client) except BlockingIOError: # 存储所有已经关闭的客户端 close_ls = [] # 存储所有需要发送数据的客户端和数据 msg_ls = [] for c in clients: try: data = c.recv(1024) if not data: c.close() close_ls.append(c) # 把要发送数据的 客户端 和数据存储到列表中 单独发送 msg_ls.append((c,data)) except BlockingIOError: pass except ConnectionResetError: c.close() close_ls.append(c) # 处理发送数据 # 已经发送完成的客户端和数据 sended_msg = [] for client_and_data in msg_ls: c = client_and_data[0] data= client_and_data[1] try: c.send(data.upper()) # 加入待删除列表 sended_msg.append(client_and_data) except BlockingIOError: pass # 将已经发送成功的数据从待发送列表中删除 for i in sended_msg: msg_ls.remove(i) sended_msg.clear() # 把已经关闭的连接从 所有客户端列表中删除 for i in close_ls: clients.remove(i) close_ls.clear()