Python---select模块的使用

2 篇文章 0 订阅

select vs epoll

  • 连接数量不高但是很活跃select
  • 连接数量搞但是不活跃 epoll

select模块的使用:

select会监听socket或者文件描述符的I/O状态变化,并返回变化的socket或者文件描述符对象

select(rlist, wlist, xlist[, timeout]) -> (rlist, wlist, xlist)

这是Python select方法的原型,接收4个参数

  1. rlist:list类型,监听其中的socket或者文件描述符是否变为可读状态,返回那些可读的socket或者文件描述符组成的list
  2. wlist:list类型,监听其中的socket或者文件描述符是否变为可写状态,返回那些可写的socket或者文件描述符组成的list
  3. xlist:list类型,监听其中的socket或者文件描述符是否出错,返回那些出错的socket或者文件描述符组成的list
  4. timeout:设置select的超时时间,设置为None代表永远不会超时,即阻塞。

注意:

  1. Python的select方法在Windows和Linux环境下的表现是不一样的,Windows下它只支持socket对象,不支持文件描述符(file descriptions),而Linux两者都支持。

  2. 我们可以通过打印来查看select模块提供的作用,返回的rlist,wlist只会返回有改变的监听对象,如果没有改变的函数,那么整个程序会阻塞住

  3. 如果我们想要加入新的连接,那么我们只需要把连接对象放进rlist即可,当有数据过来的时候,那么连接就会发生改变(文件描述符),select函数就会帮我们监听到

  4. 如果我们想发送数据,那么我们可以把conn加入到wlist,因为发送数据需要我们去输出流数据,然后等待select把wlist里面的消息取出来,我们就可以发送数据了


# python select io多路复用测试代码
# 1. 简单的使用select来进行客户端多连接

import select
import socket
import time

# select 把socket放入 select中,然后每当有一个连接过来,把连接conn放入select模型里面去

port = 19834
ip = "127.0.0.1"

ss = socket.socket()
ss.bind((ip, port))
ss.listen(10)

readable_list = [ss]


while 1:
    # print('listen again')
    rlist, wlist, xlist = select.select(readable_list, [], [],5)
    # 如果遍历出来的
    print('listen to the readable sockets',rlist)
    print('length of the readable sockets',len(rlist))
    print('length of the total sockets', len(readable_list))
    for i in rlist:
        if i is ss:
            #如果ss准备就绪,那么说明ss就可以接受连接了,当ss接受到连接
            #那么把连接返回readlist
            conn,addr = i.accept()
            readable_list.append(conn)

注意点 每次我们都需要把send的conn给移除出wlist才行,不然每次conn都会准备好写入,无限的循环

1. 简单的使用select来进行客户端多连接:
import select
import socket
import time

#select 把socket放入 select中,然后每当有一个连接过来,把连接conn放入select模型里面去
port = 19860
ip = "127.0.0.1"
ss = socket.socket()
ss.bind((ip, port))
ss.listen(10)
read_list = [ss]
write_list = []
msg_list = dict()
while 1:
    # print('listen again')
    rlist, wlist, xlist = select.select(read_list, write_list, [], 5)
    for i in rlist:
        if i is ss:
            # 如果ss准备就绪,那么说明ss就可以接受连接了,当ss接受到连接
            # 那么把连接返回readlist
            conn, addr = i.accept()
            read_list.append(conn)
        # 如果不是socket对象,那么就是conn连接对象了,如果是conn连接对象,那么就代表有
        # 读入数据的变化,对应recv方法
        else:
            try:
                data = i.recv(1024)
                # 如果接受不到数据了 则说明连接已经关闭了
                if not data:
                    print('connecting close')
                    read_list.remove(i)
                    break
                # 我们去发送数据,但是我们要把conn准备好了再去发送
                # 所以首先把数据存在一个dict中msg_list,然后再等他准备好的时候
                # 再去发送
                msg_list[i] = [data]
                if i not in write_list:
                    write_list.append(i)
            except Exception:
                read_list.remove(i)

    for j in wlist:
        # 把对应各自的消息取出来
        msg = msg_list[j].pop()
        try:
            j.send(msg)
            # 回复完成后,一定要将outputs中该socket对象移除
            write_list.remove(j)
        except Exception:
            # 如果报错就所以连接或者已经断开了,那么我们就把他移出出去
            write_list.remove(j)
  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值