代码如下:
import socket
import time
import select # 必须导入select才可以用epoll
def main():
tcp_socket=socket.socket(socket.AF_INET,socket.SOCK_STREAM )
tcp_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR,1) # 设置套接字可被重复使用,以便于有多个客户端连接时不会报错。
tcp_socket.setblocking(False) # 设置套接字为非堵塞状态
tcp_socket.bind(("127.0.0.1",7890))
tcp_socket.listen(128)
epl=select.epoll() #创建一个epoll对象
epl.register(tcp_socket.fileno(),select.EPOLLIN) #将监听套接字tcp_socket的fileno注册到epl对象中
epl_event_dic=dict()
while True:
fd_event_list=epl.epoll() # 默认为堵塞,直到操作系统监听到时间epl.epoll 是由(fileno,event)一个个个元组组成的列表
for fd,event in fd_event_list:# 遍历fd_event_list(编号,事件)列表,并同时对里面的元组拆包。
# 关于epoll我是这么理解的,就相当于上厕所,厕所外面排队的区域,凡是被创建了epoll对象的各种tcp_socket,client_socket,就是排队的人,event类似于大小号(在这里面指accept(),recv())。人群里面谁谁谁要上厕所了,就自动站到这片区域里面来。(至于操作系统怎么让他自动站到这片区域,暂时不懂,姑且先这样理解)
if fd == tcp_socket.fileno(): # 如果tcp_socket站到列表里面来了,说明操作系统监听到连接信号让他做好准备调用accept()
client_socket,client_addr=tcp_socket.accept()
client_socket.setblocking(False)
epl.register(client_socket.fileno(), select.EPOLLIN) # 对接收到的client_socket,也创建一个epoll对象
epl_event_dic[client_socket.fileno()]=client_socket # 每接受到一个客户端连接,相应的将为这个客户端服务的套接字client_socket的epl编号和client_socket 一一对应起来,存放到事先设定好的字典中
# 要注意fd_event_list中存放的只是socket的编号,而不是socket本身,而不是socket本身,所以要用字典把他们对应存储起来,以方便在下面接收数据的时候查找使用
elif event== select.EPOLLIN:
# 判断已经链接的套接字是否有数据发过来
recv_data=epl_event_dic[fd].recv(1024).decode("utf-8")# 通过epl编号,从字典中找到对应的socket来接收数据
if recv_data:# 如果接受到的数据不为空,说客户端在正常发数据
print(recv_data)
else:# 如果接收到的数据为空,说明客户端已经调用close()
epl_event_dic[fd].close() #关闭为这个客户端服务的client_socket
epl.unregister(fd) # 从epl中取消注册为这个客户端服务的套接字
del epl_event_dic[fd] # 销毁这个socket 释放内存
tcp_socket.close()
if __name__ == "__main__":
main()
"D:\new file\python-3.6.4 install\python.exe" "D:/new file/正则和http协议/单线程单进程优化-epoll.py"
Traceback (most recent call last):
File "D:/new file/正则和http协议/单线程单进程优化-epoll.py", line 37, in <module>
main()
File "D:/new file/正则和http协议/单线程单进程优化-epoll.py", line 11, in main
epl=select.epoll() #创建一个epoll对象
AttributeError: module 'select' has no attribute 'epoll'
进程已结束,退出代码1
运行报错,提示AttributeError: module ‘select’ has no attribute ‘epoll’
百度了下好多网友说是跟操作系统有关,windows下不能使用。
在官网https://docs.python.org/3/library/select.html#module-select描述最开始就有下面一堆文字:
这里是引用-This module provides access to the select() and poll() functions available in most operating systems, devpoll() available on Solaris and derivatives, epoll() available on Linux 2.5+ and kqueue() available on most BSD. Note that on Windows, it only works for sockets; on other operating systems, it also works for other file types (in particular, on Unix, it works on pipes). It cannot be used on regular files to determine whether a file has grown since it was last read.
里面说了select 里面的epoll()适用于 Linux 2.5+。