socket.recv(recv_size)何时返回?

2024-05-17 14:20:01 发布

您现在位置:Python中文网/ 问答频道 /正文

通过测试,我得出结论,在以下三种情况下,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.py时,server.py回声:

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

我的结论正确吗?我在哪里可以看到关于#3的官方描述?


Tags: 数据py客户端datasizeserver情况socket
3条回答

我认为你的结论是正确的,但不准确。

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

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

是的,你的结论是正确的。socket.recv是阻塞调用。

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

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

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

我以前和socket.setblocking有过一些问题,但是如果你想的话可以试试。

它将具有与底层recv-libc调用相同的行为请参见man page以获取行为的正式描述(或阅读sockets api的更多general description)。

相关问题 更多 >