python selector,python中的select
Python的select()方法直接调用操作系统的IO接口。它监视套接字、打开的文件和管道(使用fileno()方法的所有文件句柄)何时变得可读和可写,或者何时出现通信错误。select()使同时监控多个连接变得容易。而且这比写一个很长的循环来等待和监控多客户端连接更有效率,因为select是直接通过操作系统提供的C的网络接口来操作的,而不是通过Python的解释器。
注意:Python的select()方法适用于UNIX操作系统,不适用于Windows操作系统。
接下来,通过echo server的例子,我们想知道select如何通过单个进程同时处理多个非阻塞套接字连接。
导入选择
导入套接字
importsys
导入队列
#CreateaTCP/IPsocket
server=socket.socket(socket。AF_INET,socket。袜子_流)
server.setblocking(0)
#Bindthesockettotheport
服务器地址=(本地主机,10000)
printsys.stderr, starting upon % sport % s % server _ address
server.bind(服务器地址)
#Listenforincomingconnections
Server.listen(5)相关推荐:《Python基础教程》
select()方法接收并监视三个通信列表。第一个是所有的输入数据,也就是外部发来的数据。第二个是监控和接收所有外发数据(外发数据),第三个是监控错误信息。接下来,我们需要创建两个列表来包含要发送给select()的输入和输出信息。
# Socketsfromwhichweexpecttoread
输入=[服务器]
#Socketstowhichweexpecttowrite
Outputs=[]以上列表中服务器的主循环程序将处理客户端的所有传入连接和数据。我们现在的服务器需要等待连接可写后再来,然后接收数据并返回(所以接收到数据后不会立即返回),因为每个连接都要先把输入或输出的数据缓存到队列中,然后通过select取出再发送一次。
# outgoing message queues(socket : queue)
Message_queues={}通过服务器主循环在这些列表中添加和删除连接。由于这个版本的服务器将在发送任何数据之前等待套接字变得可写(而不是立即发送回复),每个传出连接都需要一个队列作为通过它发送的数据的缓冲区。
下面是这个程序的主循环。当调用select()时,它将阻塞并等待,直到新的连接和数据进入。
# waitforatlestoneofthesocketstobereadyforprocessing
printsys.stderr, nwaitingforthenextevent
可读、可写、异常
=select.select(inputs,outputs,inputs)当你把inputs,outputs,exceptional(这里跟inputs共用)传给select()后,它返回3个新的list,我们上面将他们分别赋值为readable,
writable,exceptional, 所有在readable list中的socket连接代表有数据可接收(recv),所有在writable list中的存放着你可以对其进行发送(send)操作的socket连接,当连接通信出现error时会把error写到exceptional列表中。
Readable list 中的socket 可以有3种可能状态,第一种是如果这个socket是main "server" socket,它负责监听客户端的连接,如果这个main server socket出现在readable里,那代表这是server端已经ready来接收一个新的连接进来了,为了让这个main server能同时处理多个连接,在下面的代码里,我们把这个main server的socket设置为非阻塞模式。
#Handleinputs
第二种情况是这个socket是已经建立了的连接,它把数据发了过来,这个时候你就可以通过recv()来接收它发过来的数据,然后把接收到的数据放到queue里,这样你就可以把接收到的数据再传回给客户端了。
else:
第三种情况就是这个客户端已经断开了,所以你再通过recv()接收到的数据就为空了,所以这个时候你就可以把这个跟客户端的连接关闭了。
else:
outputs.remove(s) #既然客户端都断开了,我就不用再给它返回数据了,所以这时候如果这个客户端的连接对象还在outputs列表中,就把它删掉。
inputs.remove(s)#inputs中也删除掉
对于writable list中的socket,也有几种状态,如果这个客户端连接在跟它对应的queue里有数据,就把这个数据取出来再发回给这个客户端,否则就把这个连接从output list中移除,这样下一次循环select()调用时检测到outputs list中没有这个连接,那就会认为这个连接还处于非活动状态。
#Handleoutputs
最后,如果在跟某个socket连接通信过程中出了错误,就把这个连接对象在inputsoutputsmessage_queue中都删除,再把连接关闭掉。
#Handle"exceptionalconditions"
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。