多路复用--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()

猜你喜欢

转载自www.cnblogs.com/wenchen/p/10225676.html
今日推荐