Python IO多路复用之——epoll方案【笔记+源码】

poll   --> 支持 linux unix  不支持windows 和poll方案在使用上只是多了个e

1.创建poll对象

p = select.poll()

2.添加注册事件

p.register(s,POLLIN | POLLERR)

POLLIN   POLLOUT   POLLERR   POLLHUP   POLLNVAL

相当于  rlist   wlist     xlist     断开      无效数据

p.unregister(s) 从关注事件中移除

3.阻塞等待IO发生

events = p.poll()

功能:阻塞等待IO发生

返回值: events 是一个列表,列表中给每一个元素都是一个元组,代表一个发生的IO事件

[(fileno,event),(),()....]  fileno:就绪IO的文件描述符 event:具体就绪事件

* 需要通过文件描述符(fileno)找到对应的IO对象

{s.fileno():s}

4.处理具体的IO

准备文件:

    epoll_server.py 用做服务端

    tcp_c.py 用做用户端


epoll_server.py 代码:


from socket import * 

from select import *


#创建套接字作为我们关注的IO

s = socket()

s.setsockopt(SOL_SOCKET,SO_REUSEADDR,1)

s.bind(('0.0.0.0',8888))

s.listen(5)


#创建poll对象

p = epoll()


#fileno ---> IO对象的字典

fdmap = {s.fileno():s}


#注册关注的IO

p.register(s,EPOLLIN | EPOLLERR)


while True:

    #进行IO监控

    events = p.poll()

    for fd,event in events:

        if fd == s.fileno():

            c,addr = fdmap[fd].accept()

            print("Connect from",addr)

            #添加新的关注事件

            p.register(c,EPOLLIN | EPOLLHUP)

            fdmap[c.fileno()] = c

        elif event & EPOLLIN:    

            data = fdmap[fd].recv(1024)

            if not data:

                #客户端退出,从关注事件移除

                p.unregister(fd)

                fdmap[fd].close()

                del fdmap[fd]

            else:

                print(data.decode())

                fdmap[fd].send(b'Receive')

    


tcp_c.py代码:


from socket import *

import time


#创建套接字

sockfd = socket(AF_INET,SOCK_STREAM)


#发起连接

server_addr = ('127.0.0.1',8888)

sockfd.connect(server_addr)

i = 0

while True:

data = input('发送>>')

#data = '哈哈'+str(i)

sockfd.send(data.encode())

data = sockfd.recv(1024)

print('接收到:',data.decode(),i)

i += 1


sockfd.close()


tcp_c.py代码:


最后编辑于:2019/10/24作者: 牛逼PHP

发表评论