"""
poll : linux,unix
1.创建poll对象 p=select.poll()
2.注册关注的IO事件 p.register(fd,event)
p.register(sockfd,POLLIN|POLLERR)
3.取消对IO的关注 p.unregister(fd) fd:IO对象或者IO对象的fileno
4.阻塞等待监控的IO事件发生 events=p.poll()
返回的是元组格式[(fileno,event),()...] 文件描述符和事件类型
实现步骤 :
1.创建套接字
2.将套接字register加入关注
3.创建查找字典,并维护
4.循环监控IO事件
5.处理发生的IO
epoll用法相似将poll改成epoll
"""
from socket import *
import select
# 创建tcp套接字
soc = socket(AF_INET, SOCK_STREAM)
# 开启端口立即重用
soc.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
# 绑定服务器地址
soc.bind(("127.0.0.1", 9090))
# 开启监听服务
soc.listen(3)
# 创建字典,并以套接字描述符为键,套接字为值,添加字典对象
# 始终与register的IO保持一致
dic = {soc.fileno(): soc}
# 创建poll对象
p = select.poll()
# 加入关注,并监控读取事件发生
p.register(soc, select.POLLIN)
print("waiting connect ...")
# 循环等待接收客户端连接请求
while True:
# 阻塞等待IO事件发生(返回值是一对对元组组成(IO描述符,监控事件类型))
event = p.poll()
# 循环遍历列表,查看那个IO就绪,就处理
for so, even in event:
# 区分那个IO就绪
if so == soc.fileno():
c, addr = dic[so].accept()
print("connect from ", addr)
# 关注客户端连接套接字
p.register(c, select.POLLIN | select.POLLERR)
# 维护字典,更新数据
dic[c.fileno()] = c
elif even & select.POLLIN:
data = dic[so].recv(1024).decode()
if not data:
# 取消对IO的关注
p.unregister(so)
# 关闭IO套接字
dic[so].close()
# 从字典中移除
del dic[so]
continue
print("c>>", data)
dic[so].send(b"OK")
06-07
177
