阻塞套接字与选择
我正在玩弄套接字(sockets),对使用阻塞套接字和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)
因为它们是阻塞套接字,所以在测试列表中的套接字是否有数据可读时,select会一直阻塞吗?
2 个回答
2
select()
这个函数会一直等待,直到其中一个套接字(也就是网络连接)有数据可以读取。它不是只检查第一个套接字,而是会检查你在 readlist
变量里列出的所有套接字。
在 for sock in sread:
这行代码中,它会遍历所有有数据可以读取的套接字。
5
select()
是 C 语言中的一个接口,它会返回当前可以读取的所有套接字(也就是网络连接)。假设 Python 的封装也做了类似的事情,那么如果有多个套接字可以读取,sread
就会包含多个元素。
一个阻塞的套接字只有在没有数据时才会阻塞,也就是说,如果在调用 select()
后显示有数据,那么你可以放心地认为,接下来调用一次 recv
不会再阻塞了。