使用 select 的服务器
import select
import socket
import Queue
#create a socket
server = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
server.setblocking(False)
#set option reused
server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR , 1)
server_address= ('localhost',10001)
server.bind(server_address)
server.listen(10)
#sockets from which we except to read
inputs = [server]
#sockets from which we expect to write
outputs = []
#Outgoing message queues (socket:Queue)
message_queues = {}
#A optional parameter for select is TIMEOUT
timeout = 10
while inputs:
print "waiting for next event"
#--------------------------------------------------
readable , writable , exceptional = select.select(inputs, outputs, inputs)
#--------------------------------------------------
for temp in readable:
print temp
print "writable:",writable
print "exceptional",exceptional
# When timeout reached , select return three empty lists
if not (readable or writable or exceptional) :
print "Time out ! "
break;
for s in readable :
if s is server:
# A "readable" socket is ready to accept a connection
connection, client_address = s.accept()
print " connection from ", client_address
connection.setblocking(0)
inputs.append(connection)
message_queues[connection] = Queue.Queue()
...........................略
创建十个 socket 用于连接服务器
import socket
messages = ["This is the message" ,
"It will be sent" ,
"in parts "]
print "Connect to the server"
server_address = ("localhost",10001)
#Create a TCP/IP sock
socks = []
for i in range(10):
socks.append(socket.socket(socket.AF_INET,socket.SOCK_STREAM))
for s in socks:
s.connect(server_address)
counter = 0
for message in messages :
#Sending message from different sockets
for s in socks:
counter+=1
print " %s sending %s" % (s.getpeername(),message+" version "+str(counter))
s.send(message+" version "+str(counter))
#Read responses on both sockets
for s in socks:
data = s.recv(1024)
print " %s received %s" % (s.getpeername(),data)
if not data:
print "closing socket ",s.getpeername()
s.close()
问题:
( 1 )服务器例子中的 select 函数是在一个怎么样的条件下才会返回?
( 2 )是不是只要有一个 socket 进行连接就会进行返回?还是说等到十个 socket 都连接了才返回?
( 3 )可以的话,讲讲 select 函数具体的运作过程?求解惑, thx
1
RTNelo 2015-10-07 18:39:23 +08:00
|
2
yang2yang OP 好的,其实我也是看过类似的文档。但是,可能我没看到,或者说不能完全理解(毕竟 English 不是很好 。。。。)刚才也是读了这个文档,在这个官方文档中还是没有提到 select 函数在 timeout 不填的时候返回时,是等到全部的 socket 连接入,还是只要有一个 socket 连入就返回。下面这两句应该是指 timeout 有值和 timeout 为 0 时的情况??还是说为 0 的情况和不填的情况是一样的?
When the timeout argument is omitted the function blocks until at least one file descriptor is ready.A time-out value of zero specifies a poll and never blocks. |
3
mckelvin 2015-10-07 21:57:12 +08:00
@yang2yang 上面的英语描述已经解答了你的疑惑了啊!
> 下面这两句应该是指 timeout 有值和 timeout 为 0 时的情况??还是说为 0 的情况和不填的情况是一样的? - 不指定 timeout 的情况下,只要有 >= 1 个文件描述符响应了就立即返回,否则一直阻塞着。 - timeout = 0 的情况下,永远不阻塞(立即返回) - timeout > 0 的情况下,有 >= 1 个文件描述符响应了就立即返回,如果过了 timeout 时间一个文件描述符都没响应的话,那就不等待了,立即返回。 建议阅读: - http://www.ulduzsoft.com/2014/01/select-poll-epoll-practical-difference-for-system-architects/#comment-39719 |
4
yang2yang OP 谢谢回复的各位,明白了
|
5
ryd994 2015-10-07 23:39:37 +08:00 via Android
要是必须全部响应才返回的话,还要 select 干嘛?直接一个个 blocking 地读过去不就完了吗
|