2011-08-24 103 views
32

从测试中,我得出结论,在以下三种情况下,socket.recv(recv_size)将返回。什么时候socket.recv(recv_size)返回?

  1. 连接关闭后。例如,客户端端 调用socket.close()或发生任何套接字错误,它将返回 空字符串。

  2. 有些数据来了,数据的大小大于recv_size

  3. 有些数据来了,数据的大小小于recv_size,短时间内没有更多的数据(我发现0.1s会工作)。

更多关于#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.pyserver.py回声:

12345 EOF 
aaaaaaaaaa EOF 
aaaaaaaaaa EOF 
aaaaaaaaaa EOF 
aaaaaaaaaa EOF 
aaaaaaaaaa EOF 

我的结论是否正确?我在哪里可以看到有关#3的官方说明?

+0

http://docs.python.org/library/socket.html#socket.socket.recv – mouad

+7

谢谢,但手册没有回答我的问题。 – redice

+3

这里怎么样:http://linux.die.net/man/2/recv – mouad

回答

18

是的,你的结论是正确的。 socket.recv是一个阻塞呼叫。

socket.recv(1024)最多可以读取1024个字节,如果没有数据正在等待读取,则会被阻止。如果您没有读取所有数据,则不会阻止对socket.recv的其他呼叫。

socket.recv如果连接关闭或出现错误,也将以空字符串结尾。

如果你想要一个无阻塞的套接字,你可以使用select模块(比使用套接字更复杂一点),或者你可以使用socket.setblocking

我在过去有过socket.setblocking的问题,但如果您愿意,可随时尝试。

+0

我没有看到关于我的结论3)的任何官方描述。 – redice

+0

socket.recv将读取准备好在recv调用时读取的内容。无论读取的数量是否小于最大大小,套接字只要能够读取数据就会解除阻塞。 – Martin

+1

如果您给出正确的标志,您也可以调用recv()作为非阻塞: 'socket.recv(10240,0x40)#0x40 = MSG_DONTWAIT aka O_NONBLOCK' 请注意,您必须赶上 '[Errno 11 ]资源暂时不可用 当没有输入数据时发生异常。 – Ray

相关问题