epoll版-TCP服务器
1.没有最⼤并发连接的限制,能打开的FD(指的是⽂件描述符,通俗的理解 就是套接字对应的数字编号)的上限远⼤于1024。
2.效率提升,不是轮询的⽅式,不会随着FD数⽬的增加效率下降。只有活 跃可⽤的FD才会调⽤callback函数;即epoll最⼤的优点就在于它只管 你“活跃”的连接,⽽跟连接总数⽆关,因此在实际的⽹络环境中,epoll 的效率就会远远⾼于select和poll
直接上代码
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(10)
#创建?个epoll对象
epoll=select.epoll()
#将创建的套接字添加到epoll的事件监听中
epoll.register(s.fileno(),select.EPOLLIN | select.EPOLLET)
connections={}
addresses={}
#循环等待客户端的到来或者对方发送数据
while True:
#epoll 进行fd扫描的地方--未指定超时时间则为阻塞等待
epoll_list=epoll.poll()
#对事件进行判断
#fd 文件描述符
for fd,events in epoll_list:
#如果是s创建的套接字被激活
if fd==s.fileno():
conn,addr=s.accept()
print("新的客户端的到来{}".format(str(addr)))
#将conn和addr信息分别保存起来
connections[conn.fileno()]=conn
addresses[conn.fileno()]=addr
#向epoll中注册 连接scoket的可读性事件
epoll.register(conn.fileno(),select.EPOLLIN | select.EPOLLET)
elif events==select.EPOLLIN:
#从激活fd上接收
reveData=connections[fd].recv(1024)
if len(reveData)>0:
print("recv:{}".format(reveData))
else:
#从epoll中移除该连接 fd
epoll.unregister(fd)
#server方 主动关闭连接fd
connections[fd].close()
print("{}-------下线------".format(str(addresses[fd]))