43 非阻塞 io多路复用

将阻塞转成非阻塞

import socket
sk = socket.socket()
sk.bind(('127.0.0.1',9090))
sk.setblocking(False)
sk.listen()
conn_l = []
del_l = []
while True: rf                
    try:
        conn,addr = sk.accept()
        conn_l.append(conn)
    except BlockingIOError as e:
        for conn in conn_l:
            try:
                ret = conn.recv(1024)
                if ret:
                    print(ret)
                    conn.send(b'hello')
                else:
                    conn.close()
                    del_l.append(conn)
            except (BlockingIOError,OSError) :pass
        for conn in del_l:
            conn_l.remove(conn)
        del_l.clear()
View Code
 TCP协议来说,如果对方关闭了连接
# 另一方有可能继续 接收 空消息 或者 报错
# 背代码
# 将具体的情况套到代码中 将逻辑理顺
# 理解之前IO多路复用的那张图
# 什么叫IO多路复用
    # io多路复用是操作系统提供的一种 监听 网络IO操作的机制
    # 监听三个列表
    # 当某一个列表有对应的事件发生的时候
    # 操作系统通知应用程序
    # 操作系统根据返回的内容做具体的操作
# 对于只有一个对象需要监听的情况  IO多路复用并无法发挥作用
# 对于并发接收网络请求的应用场景  IO多路复用可以帮助你在节省CPU利用率和操作系统调用的基础上完成并发需求
# IO多路复用
    # select 是windows上的机制 轮询的方式来监听每一个对象是否有对应的事件发生的,数据越多延迟越大
    #         能够处理的对象数是有限的
    # poll  linux  和select的机制基本一致,对底层存储被监听对象的数据结构做了优化
    #         能够处理的对象个数增加了
    # epoll  linux 采用了回调函数的方式来通知应用被监听的对象有事件发生了
# IO多路复用 - 操作系统提供的
# 1.程序不能干预过程
# 2.操作系统之间的差异
import select
import socket

sk = socket.socket()
sk.bind(('127.0.0.1',9090))
sk.listen()
sk.setblocking(False)
rlst = [sk]
while True:
    rl,wl,xl = select.select(rlst,[],[])  #[sk,conn1,conn2]
    # 为什么突然把sk返回回来了?  sk对象有数据可以被读了
    # 为什么返回三个列表? 读事件的列表 写事件的列表 条件的列表
    # 为什么是列表?  有可能同时有多个被监听的对象发生读时间
    for obj in rl:
        if obj is sk:   # is的意思更精准,判断的是obj就是sk
            conn,addr = obj.accept()
            rlst.append(conn)
        else:
            try:
                ret = obj.recv(1024)
                print(ret)
                obj.send(b'hello')
            except ConnectionResetError:
                obj.close()
                rlst.remove(obj)
View Code
原文地址:https://www.cnblogs.com/daien522556/p/9401847.html