您的位置:首页 > 编程语言 > Python开发

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()
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: