socket.recv(recv_size) 什么时候返回?
通过测试,我得出结论,在以下三种情况下,socket.recv(recv_size)
会返回数据。
当连接关闭后。例如,客户端调用了
socket.close()
,或者出现了任何套接字错误,这时会返回一个空字符串。有一些数据到达,数据的大小超过了
recv_size
。有一些数据到达,数据的大小小于
recv_size
,并且在短时间内没有更多数据到达(我发现0.1秒就可以)。
关于第3点的更多细节:
#server.py
while True:
data = sock.recv(10)
print data, 'EOF'
#client1.py
sock.sendall("12345")
sock.sendall("a" * 50)
#client2.py
sock.sendall("12345")
time.sleep(0.1)
sock.sendall("a" * 50)
当我运行 client1.py
时,server.py
返回:
12345aaaaa EOF
aaaaaaaaaa EOF
aaaaaaaaaa EOF
aaaaaaaaaa EOF
aaaaaaaaaa EOF
aaaaa EOF
当我运行 client2.py
时,server.py
返回:
12345 EOF
aaaaaaaaaa EOF
aaaaaaaaaa EOF
aaaaaaaaaa EOF
aaaaaaaaaa EOF
aaaaaaaaaa EOF
我的结论正确吗?我在哪里可以看到关于第3点的官方说明?
3 个回答
我觉得你的结论是对的,但不够准确。
根据文档的说明,socket.recv
主要是关注网络缓冲区的。
当套接字处于阻塞状态时,socket.recv
会在网络缓冲区有数据时返回。如果网络缓冲区里的数据量超过了 socket.recv
能处理的最大值,它就会返回它能处理的最大字节数。如果网络缓冲区里的数据量少于 socket.recv
能处理的最大值,它就会返回网络缓冲区里的所有数据。
是的,你的结论是对的。socket.recv
是一个阻塞调用。
socket.recv(1024)
最多会读取1024个字节,如果没有数据可以读取,它会一直等着。如果你没有读取完所有的数据,下一次调用 socket.recv
就不会再阻塞了。
如果连接关闭了或者出现了错误,socket.recv
也会返回一个空字符串。
如果你想要一个非阻塞的socket,可以使用select模块(这比单纯使用socket要复杂一些),或者你可以使用 socket.setblocking
。
我以前在使用 socket.setblocking
时遇到过问题,但如果你想试试,可以随便用。