我可以说 socket.send() "flushed"/"resets" 这里的 TCP 流吗?

Can I say that socket.send() "flushed"/"resets" the TCP stream here?

我有一个简单的服务器-客户端程序:

server.py中:

import socket

server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

server_socket.bind(("127.0.0.1", 1234))
server_socket.listen()
connection_socket, address = server_socket.accept()

with connection_socket:
    data = connection_socket.recv(1000)
    connection_socket.send(bytearray([0x0]))
    print(data)


server_socket.close()

client.py中:

import socket

client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

client_socket.connect(("127.0.0.1", 1234))
client_socket.send(bytearray([0x0, 0x1, 0x2]))
print(client_socket.recv(1))
client_socket.send(bytearray([0x3, 0x4, 0x5]))

client_socket.close()

这是我认为正在发生的事情:

我所知道的 TCP 协议是“基于流”的。我读过 here recv 阻塞 IO,直到我的 1000 字节请求得到满足。这似乎被服务器发出的 send 或客户端发出的 recv 打断了。未收到以下 3 个字节。

这些假设是否正确?如果不是,这里到底发生了什么?

在此先感谢您的帮助!

I've read here that recv blocks IO until my request of 1000 bytes has been fulfilled.

这是错误的。 recv 阻塞,直到收到 至少一个 字节。给定的数字只是指定了应该读取的最大字节数,即既不是确切数字也不是最小数字。

The following 3 bytes go unreceived.

在这种特定情况下,很可能一次收到了 1000 个字节,剩下 3 个字节未读。如果发送大量数据,尤其是通过具有低 MTU 的链接(即本地网络、WiFi 与本地主机流量),则情况有所不同。在这里可以看出,在单个 recv.

期间仅接收到部分预期数据

即使 send 将发送 all 给定数据的假设也是错误的:send 最多只会发送 [=36] =] 给定的数据。需要实际检查 return 值以查看实际发送了多少。如果您想发送所有内容,请改用 sendall

Can I say that socket.send() “flushed”/“resets” the TCP stream here?

没有。 sendrecv 仅在套接字写入和读取缓冲区上工作。它们实际上不会导致发送或接收。这是由 OS 代替完成的。 send 只是将数据放入套接字写入缓冲区,OS 最终将传输此数据。但是,这种传输并非在所有情况下都立即完成。如果有未完成的未确认数据,发送可能会延迟,直到数据被确认(细节取决于 TCP window)。如果缓冲区中只有少量数据,OS 可能会等待应用程序使用更多数据调用 send 以保持较低的传输开销(NAGLE 算法)。

因此“flush”这个词在这里没有实际意义。而“重置”实际上意味着与 TCP 完全不同的东西——即使用 RST 标志强行断开连接。所以不要在这种情况下使用这些短语。