• Python——IO多路复用之select模块epoll方法


    Python——IO多路复用之select模块epoll方法

    使用epoll方法实现IO多路复用,使用方法基本与poll方法一致,epoll效率要高于select和poll。

    .
    ├── epoll_client.py
    ├── epoll_server.py
    └── settings.py

    # settings.py
    
    HOST = 'localhost'
    PORT = 5555
    buffersize = 1024
    ADDR = HOST, PORT
    # poll_server.py
    
    from settings import *
    from select import *
    from socket import *
    
    s = socket()
    s.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)  # 设置端口可立即重用
    s.bind(ADDR)
    s.listen()
    
    # 创建epoll对象
    p = epoll()
    
    # 创建地图(字典)
    fdmap = {s.fileno(): s}
    
    # 注册关注(事件)
    p.register(s, EPOLLIN | EPOLLERR)
    # EPOLLIN 对应select方法中的参数rlist         -> 等待处理的IO事件
    # EPOLLOUT 对应select方法中的参数wlist     -> 主动处理的IO事件
    # EPOLLERR 对应select方法中的参数xlist        -> 出错处理的IO事件
    
    while True:
        # 进行IO监控
        # events = [(fileno, event), ...]
        try:
            events = p.poll()
        except KeyboardInterrupt:
            print('KeyboardInterrupt: Ctrl+C to exit')
            break
    
        for fd, event in events:
            if fd == s.fileno():
                # 从地图中找到fd对应的对象
                conn, addr = fdmap[fd].accept()
                print('Connect from', addr)
                # 注册关注
                p.register(conn, EPOLLIN)
                # 添加到地图中
                fdmap[conn.fileno()] = conn
            else:
                data = fdmap[fd].recv(buffersize)
                if not data:
                    p.unregister(fd)  # 取消注册
                    fdmap[fd].close()  # 关闭套接字
                    del fdmap[fd]  # 从地图中删除
                else:
                    print(fdmap[fd].getpeername(), data.decode())
                    fdmap[fd].send(b'Roger that!')
    s.close()
    print('El Fin')        
    # client.py
    
    from socket import *
    from settings import *
    
    s = socket()
    s.connect(ADDR)
    
    while True:
        data = input('>> ')
        if not data:
            break
        s.send(data.encode())
        print(s.recv(buffersize).decode())
    
    s.close()
    Resistance is Futile!
  • 相关阅读:
    线程执行器(一)
    修改锁的公平性
    Spark学习视频整合
    使用读写锁实现同步数据访问
    使用锁实现同步
    使用工厂类创建线程
    线程的分组
    android手机状态解释,比方android.os.Build.VERSION.SDK
    Android-Dalvik指令集
    selenium使用Xpath定位之完整篇
  • 原文地址:https://www.cnblogs.com/noonjuan/p/11281780.html
Copyright © 2020-2023  润新知