首页 > 编程语言 > 详细

python/网络:标准库模块select(IO多路复用实现)

时间:2021-01-05 12:22:21      阅读:39      评论:0      收藏:0      [点我收藏+]

1、多路复用的实现

  https://docs.python.org/zh-cn/3/library/select.html#module-select

  用 select模块,select模块在Windows下只有select方法。

    linux下有select、poll方法和epoll,epoll是select下的实现的一个类,它有自己的一些方法。

   select ---> windows linux unix

     poll ---> linux unix

     epoll ---> linux unix

  【1】select实现IO多路复用

    from select import *

    rs, ws, xs = select(rlist, wlist, xlist[, timeout])

    参数 : rlist ,列表, 存放我们需要等待处理的IO

         wlist, 列表, 存放我们想主动处理的IO

         xlist, 列表, 存放出错希望去处理的IO

         timeout, 超时检测

    功能 : 监控IO事件,阻塞等待监控的IO时间发生 

    返回值: rs ,列表, rlist中准备就绪的IO

        ws, 列表, wlist中准备就绪的IO

        xs, 列表, xlist中准备就绪的IO

    【注意】

        【1】在处理IO时不要形成死循环,让一个客户端单独占有服务端 

        【2】IO多路复兴形成一种可以同时处理多个IO的效果,效率较高 

技术分享图片
from socket import * 
from select import select 

s = socket()
s.setsockopt(SOL_SOCKET,SO_REUSEADDR,1)
s.bind((0.0.0.0,8888))
s.listen(5)

rlist = [s]
wlist = []
xlist = [s]

while True:
    print("等待IO发生")
    rs,ws,xs = select(rlist,wlist,xlist)
    for r in rs:
        if r is s:
            connfd,addr = r.accept()
            print("Connect from",addr)
            rlist.append(connfd)
        #表示客户端连接套接字准备就绪\‘///\\\\\\\\\\\\\\\‘
        else:
            data = r.recv(1024)
            if not data:
                #从关注列表移除
                rlist.remove(r)
                r.close()
            else:    
                print("Receive:",data.decode())
                #讲客户端套接字放入wlist
                wlist.append(r)
    for w in ws:
        w.send("这是一条回复消息".encode())
        wlist.remove(w)
    for x in xs:



        if x is s:
            s.close()
            00..
select-server-tcp
技术分享图片
from socket import * 

#创建套接字
sockfd = socket()

#发起连接
sockfd.connect((127.0.0.1,8888))

while True:
    #消息收发
    msg = input("Msg>>")
    if not msg:
        break
    sockfd.sendall(msg.encode())
    data = sockfd.recv(1024)
    print(data.decode())

sockfd.close()
tcp-client

  【2】poll方法实现IO多路复用

    【1】 创建poll对象

      p = select.poll()

    【2】 注册关注的IO

      p.register(s,POLLIN | POLLERR)

      p.unregister(s)   # 取消IO关注

      【事件类别】

          POLLIN       POLLOUT        POLLERR    POLLHUP    POLLPRI

          rlist        wlist      xlist     断开   紧急处理

    【3】 监控IO

      events = p.poll()

      功能: 监控关注的IO事件

      返回值: 返回发生的IO事件, events 是一个列表 [(fileno,evnet),(),()....] ,每个就绪IO对应列表中一个元组:(描述符,就绪事件)

      IO地图 : {s.fileno():s}

    【4】处理IO事件

    

技术分享图片
from socket import * 
from select import *

s = socket()
s.setsockopt(SOL_SOCKET,SO_REUSEADDR,1)
s.bind((0.0.0.0,8888))
s.listen(5)

#创建poll对象
p = poll()

#创建地图
fdmap = {s.fileno():s}

#添加关注
p.register(s,POLLIN | POLLERR)

while True:
    #进行IO监控
    #[(fileno,evnet),...]
    events = p.poll()
    for fd,event in events:
        if fd == s.fileno():
            #从地图中找到fd对应的对象
            c,addr = fdmap[fd].accept()
            print("Connect from",addr)
            #注册新的IO 维护地图
            p.register(c,POLLIN)
            fdmap[c.fileno()] = c 
        else:
            data = fdmap[fd].recv(1024)
            if not data:
                p.unregister(fd) #从关注移除
                fdmap[fd].close()
                del fdmap[fd]  #从地图删除
            else:
                print(data.decode())
                fdmap[fd].send(收到了.encode())
poll-server-tcp
技术分享图片
from socket import * 

#创建套接字
sockfd = socket()

#发起连接
sockfd.connect((127.0.0.1,8888))

while True:
    #消息收发
    msg = input("Msg>>")
    if not msg:
        break
    sockfd.sendall(msg.encode())
    data = sockfd.recv(1024)
    print(data.decode())

sockfd.close()
tcp-client

 

python/网络:标准库模块select(IO多路复用实现)

原文:https://www.cnblogs.com/longyuu/p/14234690.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!