socket.recv(recv_size)何时返回?

时间:2011-08-24 11:49:51

标签: python sockets

通过测试,我得出结论,在以下三种情况下,socket.recv(recv_size)将返回。

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

  2. 有些数据来了,数据大小超过recv_size

  3. 有些数据来了,数据的大小小于recv_size,并且在短时间内没有更多的数据(我发现0.1s会起作用)。
  4. 关于#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 个答案:

答案 0 :(得分:20)

是的,你的结论是正确的。 socket.recv是阻止通话。

socket.recv(1024)将读取最多1024个字节,如果没有数据等待读取则阻塞。如果您未读取所有数据,则对socket.recv的其他调用不会阻止。

如果连接关闭或出现错误,

socket.recv也会以空字符串结尾。

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

我过去曾遇到socket.setblocking的问题,但如果您愿意,可以随意尝试。

答案 1 :(得分:4)

它与基础的recv libc调用具有相同的行为,请参阅man page以获取行为的官方描述(或阅读更多general description套接字api。)

答案 2 :(得分:0)

我认为您的结论正确但不准确。

正如docs所指出的,socket.recv主要集中在网络缓冲区上。

当套接字被阻塞时,只要网络缓冲区有字节,socket.recv就会返回。如果网络缓冲区中的字节超过socket.recv可以处理的字节数,它将返回它可以处理的最大字节数。如果网络缓冲区中的字节少于socket.recv不能处理,它将返回网络缓冲区中的所有字节。