python使用select和epoll实现IO多路复用实现并发服务器
2020-12-13 03:03
标签:for 套接字 use python end 环境 ble cmd 队列 在select模块中, 有三种方法实现IO多路复用并发服务器 select的原理: 在多路复用的模型中,比较常用的有select模型和epoll模型。这两个都是系统接口,由操作系统提供。当然,Python的select模块进行了更高级的封装。 网络通信被Unix系统抽象为文件的读写,通常是一个设备,由设备驱动程序提供,驱动可以知道自身的数据是否可用。支持阻塞操作的设备驱动通常会实现一组自身的等待队列,如读/写等待队列用于支持上层(用户层)所需的block或non-block操作。设备的文件的资源如果可用(可读或者可写)则会通知进程,反之则会让进程睡眠,等到数据到来可用的时候,再唤醒进程。 这些设备的文件描述符被放在一个数组中,然后select调用的时候遍历这个数组,如果对于的文件描述符可读则会返回改文件描述符。当遍历结束之后,如果仍然没有一个可用设备文件描述符,select让用户进程则会睡眠,直到等待资源可用的时候在唤醒,遍历之前那个监视的数组。每次遍历都是依次进行判断的。 例如使用select实现echo(回显)服务器 但是在底层原理中, select和epoll 都是使用轮询原理来实现的. epoll是触发通知机制 引:https://www.jianshu.com/p/cdfddb026db0 python使用select和epoll实现IO多路复用实现并发服务器 标签:for 套接字 use python end 环境 ble cmd 队列 原文地址:https://www.cnblogs.com/070727sun/p/11065992.html
import select
import socket
import sys
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind((‘‘, 7788))
server.listen(5)
inputs = [server, sys.stdin]
running = True
while True:
# 调用 select 函数,阻塞等待
readable, writeable, exceptional = select.select(inputs, [], [])
# 数据抵达,循环
for sock in readable:
# 监听到有新的连接
if sock == server:
conn, addr = server.accept()
# select 监听的socket
inputs.append(conn)
# 监听到键盘有输入
elif sock == sys.stdin:
cmd = sys.stdin.readline()
running = False
break
# 有数据到达
else:
# 读取客户端连接发送的数据
data = sock.recv(1024)
if data:
sock.send(data)
else:
# 移除select监听的socket
inputs.remove(sock)
sock.close()
# 如果检测到用户输入敲击键盘,那么就退出
if not running:
break
server.close()
epoll的优点:
import socket
import select
# 创建套接字
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 可重复绑定
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
# 绑定本机地址端口
s.bind(("", 7788))
# 变为被动服务器
s.listen(1024)
# 创建一个epoll对象
epoll = select.epoll()
# 在epoll中注册s套接字(注意此处不是直接用是s, 而是使用s的fileno)
epoll.register(s.fileno(), select.EPOLLIN|select.EPOLLET)
# 创建两个字典, 来保存fileno和与其对应的套接字和地址
connections = {}
addresses = {}
# 开始等待客户端发送来的信息
while True:
# 对epoll中的套接字进行扫描
epollList = epoll.poll()
# 对扫描到的事件进行判断
for fd,events in epollList:
# 如果判断是s套接字
if fd == s.fileno():
conn,addr = s.accept()
print("有新的客户端到来...%s"%str(addr))
connections[conn.fileno()] = conn
addresses[conn.fileno()] = addr
epoll.register(conn.fileno(), selecte.EPOLLIN|select.EPOLLET)
# 如果是接收到了数据
elif events == select.EPOLLIN:
recvData = connections[fd].recv(1024)
if len(recvData) > 0:
print("recvData: %s"%recvData)
else:
epoll.unregister(fd)
connections[fd].close()
print("%s....offline....."%str(addresses[fd]))
文章标题:python使用select和epoll实现IO多路复用实现并发服务器
文章链接:http://soscw.com/essay/26823.html