阻塞套接字并选择
Posted
技术标签:
【中文标题】阻塞套接字并选择【英文标题】:blocking sockets and select 【发布时间】:2011-02-23 13:20:21 【问题描述】:我在玩套接字,我对在 select 中使用阻塞套接字有一些疑问。假设我只是在跟踪潜在的读者。我是否认为 select 将通过列表中的第一个套接字,如果有一些数据可用,它将返回,如果没有,它将阻塞直到 select 的超时到期?读取列表中的其他套接字什么时候会被select检查?
为了简单起见,我用一个python例子来说明:
servsock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
servsock.bind(("", 2500))
servsock.listen(15)
servsock.setblocking(1)
readlist = [servsock]
while 1:
(sread, swrite, sexc) = select.select(readlist, [], [] );
for sock in sread:
#received a connect to the server socket
if sock == servsock:
(newsock, address) = servsock.accept()
newsock.setblocking(1)
print "I got a connection from ", address
readlist.append(newsock)
newsock.send("you're connected to the select server")
else:
recv_msg = sock.recv(5)
if recv_msg == "":
(host, port) = sock.getpeername()
print "Client %s:%s closed the connection" % (host,port)
sock.close()
readlist.remove(sock)
else:
(host, port) = sock.getpeername()
print "client %s:%s sent: %s "% (host,port,recv_msg)
由于它们是阻塞套接字,所以在测试时会选择总是阻塞,以查看列表中的套接字是否有数据要读取?
【问题讨论】:
【参考方案1】:select()
C API 返回当前可读的所有套接字的列表。假设 python 的包装器也这样做,如果多个套接字是可读的,sread
将包含多个元素。
阻塞套接字只会在没有数据存在的情况下阻塞,因此在select()
调用指示有数据之后,您可以假设一个 对recv
的调用不会阻塞。
【讨论】:
所以换句话说,选择阻塞和非阻塞套接字的工作方式相同? 是的,它只告诉您数据是否可用,而不是告诉您读取是否会阻塞。如果数据可用,则读取通常不会阻塞,即使这意味着返回的数据少于recv()
的属性要求的数据。【参考方案2】:
select()
将阻塞,直到其中一个套接字有数据。它不仅检查第一个,还检查readlist
变量中的所有内容。
在for sock in sread:
中,它遍历所有要读取数据的套接字。
【讨论】:
以上是关于阻塞套接字并选择的主要内容,如果未能解决你的问题,请参考以下文章