python select.epoll
来源:互联网 发布:win10虚拟机装mac 编辑:程序博客网 时间:2024/06/05 17:40
参考:
http://www.360doc.com/content/11/1119/15/2660674_165748138.shtml
http://blog.csdn.net/my2010sam/article/details/9877717
#!/usr/bin/env python'''epoll实现服务器时,需要用到register()和unregister()方法,作用是加入和移除对象,epoll()的返回值包括了文件描述符和事件,polling的事件常量有POLLIN,读取数据POLLPRI,紧急数据POLLPOUT,文件描述符已经准备好POLLERR,文件描述符出错POLLHUP,连接丢失POLLVAL,无效请求。epoll 对象操作流程建立一个epoll对象告诉epoll对象, 对于一些socket监控一些事件.问epoll, 从上次查询以来什么socket产生了什么事件.针对这些socket做特定操作.告诉epoll, 修改监控socket和/或监控事件.重复第3步到第5步, 直到结束.销毁epoll对象.采用异步socket的时候第3步重复了第2步的事情. 这里的程序更复杂, 因为一个线程需要和多个客户端交互.http://www.360doc.com/content/11/1119/15/2660674_165748138.shtml'''import socketimport selectimport argparseSERVER_HOST = ''EOL1 = b'\n\n'EOL2 = b'\n\r\n'SERVER_RESPONSE = b"""HTTP/1.1 200 OK\r\nDate: Mon, 1 Apr 2013 01:01:01 GMT\r\nContent-Type: text/plain\r\nContent-Length: 25\r\n\r\nHello from Epoll Server!"""class EpollServer(object): """ A socket server using Epoll""" def __init__(self, host=SERVER_HOST, port=0): self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) self.sock.bind((host, port)) self.sock.listen(5) self.sock.setblocking(0)#设置socket为非阻塞模式 self.sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1) print "Started Epoll Server" self.epoll = select.epoll() #建立一个epoll对象. self.epoll.register(self.sock.fileno(), select.EPOLLIN)#注册服务器socket, 监听读取事件. 服务器socket接收一个连接的时候, 产生一个读取事件. fileno是文件描述符, 是一个整型数. def run(self): """Executes epoll server operation""" try: #connections表映射文件描述符(file descriptors, 整型)到对应的socket对象上面 #requests #responses connections = {}; requests = {}; responses = {} while True: #epoll对象查询一下是否有感兴趣的事件发生, 参数1说明我们最多等待1秒的时间. 如果有对应事件发生, 立刻会返回一个事件列表 events = self.epoll.poll(1) #返回的events是一个(fileno, event code)tuple元组列表. fileno是文件描述符, 是一个整型数. for fileno, event in events: #如果是服务器socket的事件, 那么需要针对新的连接建立一个socket. if fileno == self.sock.fileno(): connection, address = self.sock.accept() connection.setblocking(0)#设置socket为非阻塞模式 self.epoll.register(connection.fileno(), select.EPOLLIN) #注册socket的read(EPOLLIN)事件. connections[connection.fileno()] = connection requests[connection.fileno()] = b'' responses[connection.fileno()] = SERVER_RESPONSE elif event & select.EPOLLIN: #如果读取事件发生, 从客户端读取新数据.(打印client http 请求头) requests[fileno] += connections[fileno].recv(1024) if EOL1 in requests[fileno] or EOL2 in requests[fileno]: #一旦完整的http请求接收到, 取消注册读取事件, 注册写入事件(EPOLLOUT), 写入事件在能够发送数据回客户端的时候产生 self.epoll.modify(fileno, select.EPOLLOUT) #打印完整的http请求, 展示即使通讯是交错的, 数据本身是作为一个完整的信息组合和处理的. print('-'*40 + '\n' + requests[fileno].decode()[:-2]) elif event & select.EPOLLOUT: # 如果写入事件发生在一个客户端socket上面, 我们就可以发送新数据到客户端了. # 一次发送一部分返回数据, 直到所有数据都交给操作系统的发送队列. byteswritten = connections[fileno].send(responses[fileno]) responses[fileno] = responses[fileno][byteswritten:] if len(responses[fileno]) == 0: self.epoll.modify(fileno, 0)#一旦所有的返回数据都发送完, 取消监听读取和写入事件. connections[fileno].shutdown(socket.SHUT_RDWR)#如果连接被明确关闭掉, 这一步是可选的. 这个例子采用这个方法是为了让客户端首先断开, 告诉客户端没有数据需要发送和接收了, 然后让客户端断开连接. elif event & select.EPOLLHUP:#HUP(hang-up)事件表示客户端断开了连接(比如 closed), 所以服务器这端也会断开. 不需要注册HUP事件, 因为它们都会标示到注册在epoll的socket. self.epoll.unregister(fileno) connections[fileno].close() del connections[fileno] finally: #在这里的异常捕捉的作用是, 我们的例子总是采用键盘中断来停止程序执行. #虽然开启的socket不需要手动关闭, 程序退出的时候会自动关闭, 明确写出来这样的代码, 是更好的编码风格. self.epoll.unregister(self.sock.fileno()) self.epoll.close() self.sock.close()if __name__ == '__main__': parser = argparse.ArgumentParser(description='Socket Server Example with Epoll') parser.add_argument('--port', action="store", dest="port", type=int, required=True) given_args = parser.parse_args() port = given_args.port server = EpollServer(host=SERVER_HOST, port=port) server.run()
0 0
- python select.epoll
- python select poll epoll
- Python-select详解(select、epoll)
- python socket的select,poll,epoll
- Select & Epoll
- epoll/select
- select/epoll
- select & epoll
- python实现select和epoll模型socket网络编程
- Python异步非阻塞IO多路复用Select/Poll/Epoll使用
- Python异步非阻塞IO多路复用Select/Poll/Epoll使用
- python下的select模块使用 以及epoll与select、poll的区别
- epoll-select的代替品
- select and epoll
- select 和 epoll比较
- select、Poll、epoll比较。
- epoll,select的区别
- epoll难以替代select
- 条码系统的 存储过程 示例
- PowerDesigner PDM生成OOM问题?
- 杭电ACm求数列的和2009
- 计算机网络——8.IPv6基础
- hdu3047 Zjnu Stadium(简单的路径压缩)
- python select.epoll
- Android UrlEncodedFormEntity() 和 StringEntity() 的区别
- Redis开源代码读书笔记一(介绍)
- Java设计模式之装饰器模式
- 二叉树的存储和构造例子
- oracle 分区表的建立
- eludehcSesruoC.207
- 简单的DIV+CSS布局
- 网站开发进阶(三十二)HTML5之FileReader的使用