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



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

Inserver.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协议是"基于流"的。我在这里读到recv阻塞IO,直到我的1000字节的请求得到满足。这似乎被服务器发出的send或客户端发出的recv打断了。以下3个字节未接收。

这些假设正确吗?如果不是,这到底是怎么回事?

提前感谢您的帮助!

我在这里读到recv阻塞IO,直到我的1000字节请求被满足。

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

以下3个字节未接收。

在这个特定的情况下,很可能一次接收1000字节,留下3字节未读。但如果发送的数据量较大,特别是在MTU较低的链路上(即本地网络、WiFi与本地主机流量),情况就不同了。这里可以看到,在单个recv期间,只有部分预期数据被接收。

即使假设send将发送所有send最多只能发送给定的数据。需要实际检查返回值,看看实际发送了多少。使用sendall代替,如果你想让所有的发送。

我可以说socket.send()"刷新"/"重置"TCP流在这里吗?

sendrecv仅在套接字写缓冲区和读缓冲区上工作。它们实际上不会引起发送或接收。这是由操作系统来完成的。send只是将数据放入套接字写缓冲区,操作系统最终将传输该数据。不过,这种传播并非在所有情况下都是立即完成的。如果有未确认的数据,发送可能会被延迟,直到数据被确认(具体取决于TCP窗口)。如果只有很少的数据在缓冲区中,操作系统可能会等待一段时间,让应用程序调用send与更多的数据,以保持低传输开销(NAGLE算法)。

因此短语"flush"在这里没有真正的意义。和";reset"实际上意味着与TCP完全不同的东西——即使用RST标志强制断开连接。所以不要在这种情况下使用这些短语。

最新更新