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()# 测试,用来打印套接字对应的文件描述符
# print s.fileno()
# print select.EPOLLIN|select.EPOLLET# 注册事件到epoll中
# epoll.register(fd[, eventmask])
# 注意,如果fd已经注册过,则会发生异常
# 将创建的套接字添加到epoll的事件监听中
epoll.register(s.fileno(),select.EPOLLIN|select.EPOLLET)connections = {}
addresses = {}# 循环等待客户端的到来或者对方发送数据
while True:# epoll 进行 fd 扫描的地方 -- 未指定超时时间则为阻塞等待epoll_list=epoll.poll()# 对事件进行判断for fd,events in epoll_list:# print fd# print events# 如果是socket创建的套接字被激活if fd == s.fileno():conn,addr=s.accept()print('有新的客户端到来%s'%str(addr))# 将 conn 和 addr 信息分别保存起来connections[conn.fileno()] = connaddresses[conn.fileno()] = addr# 向 epoll 中注册 连接 socket 的 可读 事件epoll.register(conn.fileno(), select.EPOLLIN | select.EPOLLET)elif events == select.EPOLLIN:# 从激活 fd 上接收recvData = connections[fd].recv(1024)if len(recvData)>0:print('recv:%s'%recvData)else:# 从 epoll 中移除该 连接 fdepoll.unregister(fd)# server 侧主动关闭该 连接 fdconnections[fd].close()print("%s---offline---"%str(addresses[fd]))
epoll对文件描述符的操作有两种模式:LT(level trigger)和ET(edge trigger)。LT模式是默认模式,LT模式与ET模式的区别如下:
LT模式:当epoll检测到描述符事件发生并将此事件通知应用程序,应用程序可以不立即处理该事件。下次调用epoll时,会再次响应应用程序并通知此事件。ET模式:当epoll检测到描述符事件发生并将此事件通知应用程序,应用程序必须立即处理该事件。如果不处理,下次调用epoll时
版权声明:本站所有资料均为网友推荐收集整理而来,仅供学习和研究交流使用。
工作时间:8:00-18:00
客服电话
电子邮件
admin@qq.com
扫码二维码
获取最新动态