IO多路复用之select

原理:I/O多路复用就通过一种机制,可以监视多个描述符,一旦某个描述符就绪,能够通知程序进行相应的操作。

select执行流程

  1. select需要提供要监控的数组,然后由用户态拷贝到内核态
  2. 内核态线性循环监控数组,每次都需要遍历整个数组
  3. 内核发现文件描述符状态符合操作结果,将其返回
  4. 所以对于我们监控的socket都要设置为非阻塞的,只有这样才能保证不会被阻塞

优点

  1. 基本各个平台都支持

缺点

  1. 每次调用select,都需要把fd集合由用户态拷贝到内核态,在fd多的时候开销会很大

  2. 单个进程能够监控的fd数量存在最大限制,因为其使用的数据结构是数组

  3. 每次select都是线性遍历整个数组,当fd很大的时候,遍历的开销也很大

  4. 所以对于我们监控的socket都要设置为非阻塞的,只有这样才能保证不会被阻塞

服务端

import select
import socket

socket_server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
socket_server.getsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
socket_server.bind(('', 10002))
socket_server.listen(5)

# 接收连接队列
rlist = [socket_server]
# 应答队列
wlist = []
# 错处理的IO事件
xlist = []

while True:
    # 监控IO发生
    rs, ws, xs = select.select(rlist, wlist, xlist)

    # 遍历三个返回值列表,判断哪个IO发生
    for r in rs:
        # 如果是套接字准备就绪,处理连接
        if r == socket_server:
            c, addr = r.accept()
            print("Connect from: ", addr)
            print("当前连接套接字的文件描述符:", c.fileno())
            # 将客户端套接字加入新的关注IO
            rlist.append(c)
        # 用于沟通的新客户端套接字
        else:
            data = r.recv(1024)
            if not data:
                # 客户端断开连接,将客户端套接字关闭,并且从监控列表中移除
                rlist.remove(r)
                r.close()
                continue
            print(data.decode("utf-8"))

            # 主动处理这个IO,作应答
            wlist.append(r)

    for w in ws:
        w.send(b'OK')
        wlist.remove(w)

    for x in xs:
        pass

客户端

import socket

flag = 1
s = socket.socket()
s.connect(('127.0.0.1', 10002))
while flag:
    input_msg = input('input>>>')
    if input_msg == '0':
        break
    s.sendall(input_msg.encode())
    msg = s.recv(1024)
    print(msg.decode())

s.close()
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值