epoll发展进程

此处添加一下select、poll历程及其优缺点


原理


使用步骤

  1. Create an epoll object——创建1个epoll对象
  2. Tell the epoll object to monitor specific events on specific sockets——告诉epoll对象,在指定的socket上监听指定的事件
  3. Ask the epoll object which sockets may have had the specified event since the last query——询问epoll对象,从上次查询以来,哪些socket发生了哪些指定的事件
  4. Perform some action on those sockets——在这些socket上执行一些操作
  5. Tell the epoll object to modify the list of sockets and/or events to monitor——告诉epoll对象,修改socket列表和(或)事件,并监控
  6. Repeat steps 3 through 5 until finished——重复步骤3-5,直到完成
  7. Destroy the epoll object——销毁epoll对象

伪代码

import select 导入select模块

epoll = select.epoll() 创建一个epoll对象

epoll.register(文件句柄,事件类型) 注册要监控的文件句柄和事件

事件类型:

  select.EPOLLIN    可读事件

  select.EPOLLOUT   可写事件

  select.EPOLLERR   错误事件

  select.EPOLLHUP   客户端断开事件

epoll.unregister(文件句柄)   销毁文件句柄

epoll.poll(timeout)  当文件句柄发生变化,则会以列表的形式主动报告给用户进程,timeout

                     为超时时间,默认为-1,即一直等待直到文件句柄发生变化,如果指定为1

                     那么epoll每1秒汇报一次当前文件句柄的变化情况,如果无变化则返回空

epoll.fileno() 返回epoll的控制文件描述符(Return the epoll control file descriptor)

epoll.modfiy(fineno,event) fineno为文件描述符 event为事件类型  作用是修改文件描述符所对应的事件

epoll.fromfd(fileno) 从1个指定的文件描述符创建1个epoll对象

epoll.close()   关闭epoll对象的控制文件描述符

真代码

Client

#!/usr/bin/env python
#-*- coding:utf-8 -*- import socket #创建客户端socket对象
clientsocket = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
#服务端IP地址和端口号元组
server_address = ('127.0.0.1',8888)
#客户端连接指定的IP地址和端口号
clientsocket.connect(server_address) while True:
#输入数据
data = raw_input('please input:')
#客户端发送数据
clientsocket.sendall(data)
#客户端接收数据
server_data = clientsocket.recv(1024)
print '客户端收到的数据:'server_data
#关闭客户端socket
clientsocket.close()

Server

#!/usr/bin/env python
#-*- coding:utf-8 -*- import socket
import select
import Queue #创建socket对象
serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
#设置IP地址复用
serversocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
#ip地址和端口号
server_address = ("127.0.0.1", 8888)
#绑定IP地址
serversocket.bind(server_address)
#监听,并设置最大连接数
serversocket.listen(10)
print "服务器启动成功,监听IP:" , server_address
#服务端设置非阻塞
serversocket.setblocking(False)
#超时时间
timeout = 10
#创建epoll事件对象,后续要监控的事件添加到其中
epoll = select.epoll()
#注册服务器监听fd到等待读事件集合
epoll.register(serversocket.fileno(), select.EPOLLIN)
#保存连接客户端消息的字典,格式为{}
message_queues = {}
#文件句柄到所对应对象的字典,格式为{句柄:对象}
fd_to_socket = {serversocket.fileno():serversocket,} while True:
print "等待活动连接......"
#轮询注册的事件集合,返回值为[(文件句柄,对应的事件),(...),....]
events = epoll.poll(timeout)
if not events:
print "epoll超时无活动连接,重新轮询......"
continue
print "有" , len(events), "个新事件,开始处理......" for fd, event in events:
socket = fd_to_socket[fd]
#如果活动socket为当前服务器socket,表示有新连接
if socket == serversocket:
connection, address = serversocket.accept()
print "新连接:" , address
#新连接socket设置为非阻塞
connection.setblocking(False)
#注册新连接fd到待读事件集合
epoll.register(connection.fileno(), select.EPOLLIN)
#把新连接的文件句柄以及对象保存到字典
fd_to_socket[connection.fileno()] = connection
#以新连接的对象为键值,值存储在队列中,保存每个连接的信息
message_queues[connection] = Queue.Queue()
#关闭事件
elif event & select.EPOLLHUP:
print 'client close'
#在epoll中注销客户端的文件句柄
epoll.unregister(fd)
#关闭客户端的文件句柄
fd_to_socket[fd].close()
#在字典中删除与已关闭客户端相关的信息
del fd_to_socket[fd]
#可读事件
elif event & select.EPOLLIN:
#接收数据
data = socket.recv(1024)
if data:
print "收到数据:" , data , "客户端:" , socket.getpeername()
#将数据放入对应客户端的字典
message_queues[socket].put(data)
#修改读取到消息的连接到等待写事件集合(即对应客户端收到消息后,再将其fd修改并加入写事件集合)
epoll.modify(fd, select.EPOLLOUT)
#可写事件
elif event & select.EPOLLOUT:
try:
#从字典中获取对应客户端的信息
msg = message_queues[socket].get_nowait()
except Queue.Empty:
print socket.getpeername() , " queue empty"
#修改文件句柄为读事件
epoll.modify(fd, select.EPOLLIN)
else :
print "发送数据:" , data , "客户端:" , socket.getpeername()
#发送数据
socket.send(msg) #在epoll中注销服务端文件句柄
epoll.unregister(serversocket.fileno())
#关闭epoll
epoll.close()
#关闭服务器socket
serversocket.close()

【Python网络编程】epoll用法的更多相关文章

  1. python 网络编程 IO多路复用之epoll

    python网络编程——IO多路复用之epoll 1.内核EPOLL模型讲解     此部分参考http://blog.csdn.net/mango_song/article/details/4264 ...

  2. Python 网络编程(二)

    Python 网络编程 上一篇博客介绍了socket的基本概念以及实现了简单的TCP和UDP的客户端.服务器程序,本篇博客主要对socket编程进行更深入的讲解 一.简化版ssh实现 这是一个极其简单 ...

  3. python网络编程——IO多路复用之select

    1 IO多路复用的概念 原生socket客户端在与服务端建立连接时,即服务端调用accept方法时是阻塞的,同时服务端和客户端在收发数据(调用recv.send.sendall)时也是阻塞的.原生so ...

  4. 图解Python网络编程

    返回目录 本篇索引 (1)基本原理 (2)socket模块 (3)select模块 (4)asyncore模块 (5)asynchat模块 (6)socketserver模块 (1)基本原理 本篇指的 ...

  5. Python 网络编程(一)

    Python 网络编程 socket通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄,应用程序通常通过"套接字"向网络发出请求或者应答网络请求. ...

  6. Python学习(22)python网络编程

    Python 网络编程 Python 提供了两个级别访问的网络服务.: 低级别的网络服务支持基本的 Socket,它提供了标准的 BSD Sockets API,可以访问底层操作系统Socket接口的 ...

  7. Day07 - Python 网络编程 Socket

    1. Python 网络编程 Python 提供了两个级别访问网络服务: 低级别的网络服务支持基本的 Socket,它提供了标准的 BSD Sockets API,可以访问底层操作系统Socket接口 ...

  8. python网络编程-01

    python网络编程 1.socket模块介绍 ①在网络编程中的一个基本组件就是套接字(socket),socket是两个程序之间的“信息通道”. ②套接字包括两个部分:服务器套接字.客户机套接字 ③ ...

  9. 《Python网络编程》学习笔记--使用谷歌地理编码API获取一个JSON文档

    Foundations of Python Network Programing,Third Edition <python网络编程>,本书中的代码可在Github上搜索fopnp下载 本 ...

  10. UNIX网络编程——epoll 的accept , read, write(重要)

    在一个非阻塞的socket上调用read/write函数,返回EAGAIN或者EWOULDBLOCK(注:EAGAIN就是EWOULDBLOCK). 从字面上看,意思是: EAGAIN: 再试一次 E ...

随机推荐

  1. 高性能MySQL学习总结一

    一.MySQL逻辑架构 第一层的服务不是MySQL独有的,大多数是基于网络的客户端/服务端的工具,如连接处理.授权认证.安全等等. 第二层就是MySQL的核心功能,包括查询解析.分析.优化.缓存以及所 ...

  2. 认识 YUV

    什么是 YUV YUV是一种颜色编码格式,可以说YUV流媒体是原始流数据,大部分的视频领域都在使用.与RGB类似,但RGB更多的用于渲染时,而YUV则用在数据传输,因为它占用更少的频宽.当然,实时通讯 ...

  3. Intellij IDEA设置

    代码格式化/保存时自动格式 搜索google-java-format 和 Save Actions,安装 保存时候// 自动空格 自动导包 自动换行

  4. [LeetCode]2. Add Two Numbers链表相加

    注意进位的处理和节点为null的处理 public ListNode addTwoNumbers(ListNode l1, ListNode l2) { int flag = 0; ListNode ...

  5. java时间的一些处理

    获取当前时间 System.currentTimeMillis() //第一种 Date date = new Date(); System.out.println(date.getTime()); ...

  6. Spring事务管理?

    事务管理方式: 1.编码方案,不建议使用,具有侵入性,在原有的业务代码基础上去添加事物管理代码 2.声明式事务控制,基于AOP对目标进行代理,不具有侵入性,不需要修改原来的业务代码

  7. MySQL性能分析show profiles详解

    前言 前几篇文章我们讲了什么是 MySQL 索引,explain分析SQL语句是否用到索引,以及索引的优化等一系列的文章,今天我们来讲讲Show profiles,看看SQL耗时到底出现在哪个环节. ...

  8. redis系列:分布式锁

    redis系列:分布式锁 1 介绍 这篇博文讲介绍如何一步步构建一个基于Redis的分布式锁.会从最原始的版本开始,然后根据问题进行调整,最后完成一个较为合理的分布式锁. 本篇文章会将分布式锁的实现分 ...

  9. Let’s Encrypt 通配符证书,泛域名证书申请配置

    首先你可以查看下官方提供的支持申请通配符证书的客户端列表:https://letsencrypt.org/docs/client-options/. 参考链接:https://github.com/N ...

  10. IntelliJ IDEA实用插件

    Free MyBatis plugin 插件效果 Save Actions 插件设置 勾选后Ctrl + S就会执行格式化操作,等价于格式化快捷键Alt + Ctrl + L