当使用recv(n)时,如果n大于MTU,是否保证至少读取整个第2层帧



我想知道,想象一下,如果没有数据可以从TCP套接字中读取,那么整个1492字节的帧就会到达(满(。在你的代码(C或任何支持TCP的语言(中,比如说recv 4096字节,操作系统会保证recv读取整个1492字节吗,或者内存和recv中的帧加载可能是"0";"交错";,那么recv可能会减少?

TCP是一个面向流的协议。数据是按顺序接收的,但在收到所有数据之前,您不能假设您必须调用recv多少次
由您的应用程序重复呼叫recv,直到您知道您已收到所需信息。

(1(TCP是面向流的协议。这意味着它接受来自发送器上层的数据流,并将数据流返回到接收器上层。TCP本身从IP层接收数据包,然后重建流。也就是说,在某些时候,数据包就不复存在了。理论上,在这个重建的流的某个地方,可能只有一半的插入数据包被复制到缓冲区中,但在我看来,这种情况不太可能发生。

现在,linux手册页显示

接收呼叫通常会返回任何可用数据,直到请求的数量

我会把它解释为";如果一个数据包已经到达(正确、有序等(,您将获得整个数据包的数据";。但这并不能保证。

另一方面,Windows文档指出:

recv将返回与当前可用数据一样多的数据,最多返回指定缓冲区的大小。

这听起来更像是保证。

然而,请注意,只有当数据包被正确接收,并且它是下一个有序的数据包(具有下一个预期序列号(时,才会返回数据。

(2(现在,TCP层处理完整的数据包。实际上,它不可能进行交织或其他任何操作。以太网有一个校验和,除非完全接收到数据包,否则无法计算校验和。网卡应过滤掉以太网校验和不正确的数据包。TCP还有一个校验和,它需要计算所有的数据包。因此,如果网卡已经将数据包传递给您的操作系统,那么数据应该是可用的。

(3(我认为你不能假设如果收到数据包,它就立即可用。网卡的一个非常常见的特性是TCP分段卸载,它重建部分流,并导致网卡通过一个由多个TCP数据包重建的TCP数据包。还有其他措施可以减少中断的数量,这或多或少会导致多个数据包同时混合。因此,更可能的情况是,您可能会有一些延迟,然后一次从多个数据包接收数据。

关键是,与你所描述的相反的情况很可能会发生。然而,我仍然不会编写一个应用程序来假设一次有多大的数据块可用。这否定了流的概念。

最新更新