python 异步I/O
2015-08-29 13:39
615 查看
#!usr/bin/env python #coding:utf-8 import select import socket import Queue server=socket.socket(socket.AF_INET,socket.SOCK_STREAM) server.setblocking(False) server_address=('127.0.0.1', 8000) server.bind(server_address) server.listen(5) read=[server] write=[] error=[] message_queues={} timeout=20 #select(read[],write[],error[],timeout)轮询监控3个list #所以当list比较大的时候,非常耗时 while (Ture): readlist, writelist, errorlist=select.select(read, write, error, timeout) for s in readlist: #当服务器socket可用时,接入客户端,并将客户端加入可读处进行监听 if s is server: conn, address=s.accept() con.setblocking(0) readlist.append(con) message_queues[con]=Queue.Queue() #如果客户端发来消息,则将客户端加入读队列,读取客户端消息 else: data=s.recv(1024) if data: #将数据加入队列中 message_queues[s].put(data) #标记客户端为write,准备向客户端写消息 if s not in writelist: writelist.append(s) #客户端没有发来消息,关闭连接 else: if s in writelist: writelist.remove(s) readlist.remove(s) s.close() del message_queues[s] for s in writelist: #发送消息 for s in errorlist: #处理异常 #epoll基于回调事件通知模式 #!/usr/bin/python # -*- coding: utf-8 -*- import socket, select import Queue serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) serversocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) server_address = ("192.168.1.5", 8080) serversocket.bind(server_address) serversocket.listen(1) print "服务器启动成功,监听IP:" , server_address serversocket.setblocking(0) 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] #可读事件 if event & select.EPOLLIN: #如果活动socket为服务器所监听,有新连接 if socket == serversocket: connection, address = serversocket.accept() print "新连接:" , address connection.setblocking(0) #注册新连接fd到待读事件集合 epoll.register(connection.fileno(), select.EPOLLIN) fd_to_socket[connection.fileno()] = connection message_queues[connection] = Queue.Queue() #否则为客户端发送的数据 else: data = socket.recv(1024) if data: print "收到数据:" , data , "客户端:" , socket.getpeername() message_queues[socket].put(data) #修改读取到消息的连接到等待写事件集合 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) #关闭事件 elif event & select.EPOLLHUP: epoll.unregister(fd) fd_to_socket[fd].close() del fd_to_socket[fd] epoll.unregister(serversocket.fileno()) epoll.close() serversocket.close()
相关文章推荐
- Python单元测试框架之pytest -- fixtures
- 将图片生成pkl格式的文件(多层循环)
- python有关sorted和sort
- Python入门---数据类型
- python 分布式进程
- python logging 日志模块的配置和使用
- 学习日志---python(函数式编程)
- 机器学习算法与Python实践之(八)朴素贝叶斯
- 机器学习算法与Python实践之(七)逻辑回归(Logistic Regression)
- 【Python系列1】中文分词之后输出最大长度词
- 机器学习算法与Python实践之(六)二分k均值聚类
- 机器学习算法与Python实践之(五)k均值聚类(k-means)
- Python 标准库 ConfigParser 模块 的使用
- 机器学习算法与Python实践之(四)支持向量机(SVM)实现
- 机器学习算法与Python实践之(三)支持向量机(SVM)进阶
- 机器学习算法与Python实践之(二)支持向量机(SVM)初级
- python 多线程threading
- 机器学习算法与Python实践之(一)k近邻(KNN)
- Python -定义函数
- python Property