首页 > 代码库 > python select和socket配合使用基础学习,是python标准库例子
python select和socket配合使用基础学习,是python标准库例子
# -*- coding: utf-8 -*-
# python:2.x
__author__ = ‘Administrator‘
import select,socket,sys,Queue
#作用:等待输入或者输出通道已经准备就绪的通知
#select模块允许访问特定平台的IO监视函数,可移植接口是POSIX函数select(),unix和windows都支持这个函数,poll()只支持unix,还有一些适用于unix特定变种选项
#select()是底层操作系统实现一个直接接口,会监视套接字,打开文件和管道(可以是任何有filen()方法对象,它会返回一个合法的文件描述符),这个是可读,可写的,或者出现一个通信错误,select()可以高效的同时监视多个连接
#select()服务器端例子学习
serve=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
serve.setblocking(0)#如果套接字为0,设置为非阻塞,阻塞模式
serer_address=(‘localhost‘,10000)
print >>sys.stderr,‘starting up on%s port %s‘%serer_address
serve.bind(serer_address)
serve.listen(5)
"""
select()原型是(rlist,wlist,xlist[,timeout])
rlist等待读取对象,wlist等待定稿对象,xlist等待异常对象,最后一个可选对象,指定等待时间,单位是s,select()方法返回值准备好的对象是三元组,若在timeout时间内,没有对象准备好,那么返回值是空的列表
"""
inputs=[serve]#读取
outputs=[]#写入
#服务器主循环向这些列表添加或者删除连接,由于版本服务器在发送数据之前要等待一个套接字变为可写(不是马上发出相应),所以每个输出连接都需要一个队列,作为通过这个套接字发送的数据缓冲区
message_queues={}
#服务器程序主要部分是循环,调用 select()来阻塞,并等待网络活动
while inputs:
print >>sys.stderr,‘waiting for the next event‘
readable,writable,exceptional=select.select(inputs,outputs,inputs)
#可读的套接字表示3种可能情况,如果套接字是主服务器套接字,即用来监听连接的套接字,意味它已经准备就绪,可以接受另一个到来的连接,除了将新连接添加到要监视的输入列表之外,这一部分还将客户端设置为非阻塞
for s in readable:
if s is serve:
connectiuon,client_addre=s.accept()
print >>sys.stderr,‘connection from‘,client_addre
connectiuon.setblocking(0)
inputs.append(connectiuon)
message_queues[connectiuon]=Queue.Queue()
#下一种情况是已经连接了,客户已经发数据,数据使用recv()读取,然后旋转在队列中,进行返回
else:
data=http://www.mamicode.com/s.recv(1024)
if data:
print >>sys.stderr,‘received%s form %s‘%(data,s.getpeername())
message_queues[s].put(data)
if s not in outputs:
outputs.append(s)
#没有数据可用的可读套接字来自已经断开连接端,可以关闭流
else:
print >>sys.stderr,‘closeing‘,client_addre
if s in outputs:
outputs.append(s)
inputs.append(s)
s.close()
del message_queues[s]
#对于可写连接,情况要少一些,如果对应一个连接队列中有数据,则发送下一个消息,否则,将这个连接从输出连接删除,下一次循环,select()不再指示这个套接字已经准备就绪发送数据
for s in writable:
try:
next_msg=message_queues[s].get_nowait()
except Queue.Empty:
print >>sys.stderr,‘ ‘,s.getpeername(),‘queue empty‘
outputs.remove(s)
else:
print >>sys.stderr,‘ sending %s to %s‘%(next_msg,s.getpeername())
s.send(next_msg)
#最后,如果一个套接字有错误,则关闭
for s in exceptional:
print >>sys.stderr,‘exception condition on‘,s.getpeername()
inputs.remove(s)
if s in outputs:
outputs.remove(s)
s.close()
#select()客户端程序
message=[‘this is the message‘,‘it will be sent,‘
‘in parts.‘]
serer_address=(‘localhost‘,10000)
socks=[socket.socket(socket.AF_INET,socket.SOCK_STREAM),
socket.socket(socket.AF_INET,socket.SOCK_STREAM),]
print >>sys.stderr,‘connection to%s and %s‘%(serer_address)
for s in socks:
s.connect(serer_address)
#通过各个套接字发送一次信息,写新数据之后再得到所有相应数据
for m in message:
if s in socks:
print >>sys.stderr,‘%s:sending%s‘%(s.getsockname(),m,s.send(m))
for s in socks:
data=http://www.mamicode.com/s.recv(1024)
print ‘%s:%s‘%(s.getpeername(),data)
if not data:
print >>sys.stderr,‘closeing socket‘,s.getsockname()
s.close()
python select和socket配合使用基础学习,是python标准库例子