TCP 和 UDP 数据包可以分成几部分吗?

iam*_*mnp 42 networking tcp udp

TCP 数据包可以分段到达接收方吗?

例如,如果我使用 TCP 协议发送 20 个字节,我能否 100% 确定我将一次接收 20 个字节,而不是 10 个字节然后再接收 10 个字节左右?

UDP 协议也有同样的问题。
我知道 UDP 是不可靠的,数据包根本无法到达或以不同的顺序到达,但是单个数据包呢?如果它到了,我能确定它是一个完整的包裹,而不是一块吗?

Dav*_*rtz 33

TCP数据包可以分段到达接收器吗?

是的。IP 支持分段,尽管 TCP 通常会尝试确定路径 MTU 并出于性能原因保持其数据包小于该值。碎片化会灾难性地增加数据报丢失率。如果一条路径有 10% 的丢包率,将一个数据报分片成两个数据包会使数据报丢失率接近 20%。(如果任一数据包丢失,则数据报丢失。)

不过,您不必担心这一点,TCP 层也不必担心。IP 层将数据包重新组合成整个数据报。

例如:如果我使用 TCP 协议发送 20 个字节,我能否 100% 确定我将一次接收 20 个字节,而不是 10 个字节然后再接收 10 个字节左右?

不,但这与数据包无关。从根本上说,TCP 是一种不保留应用程序消息边界的字节流协议。

UDP 协议也有同样的问题。我知道 UDP 是不可靠的,数据包根本无法到达或以不同的顺序到达,

对于 TCP 也是如此。包就是包。不同之处在于 TCP 具有内置于协议中的重试和重新排序,而 UDP 则没有。

但是1包呢?如果它到了,我能确定它是一个完整的包裹,而不是一块吗?

不,但这不是你的问题。UDP 协议处理数据报重组。这是它工作的一部分。(实际上,IP 协议为 UDP 协议执行此操作,因此 UDP 仅通过在 IP 之上分层来执行此操作。)如果数据报被拆分为两个数据包,IP 协议将为 UDP 协议重新组装它,因此您将看到完整的数据。

  • 可能值得为新手读者澄清最后一点:*您将看到完整的数据* **有问题的数据报**。如果任何一个拆分的数据包丢失,数据报就会丢失,UDP 层永远不会知道它。只要接收到数据报中的所有数据包,它们就会在 IP 层组装,然后向上传递到 UDP 层。这并不排除数据流中丢失“块”的可能性。不是学究,但是当我学习这些东西时,直到第二次或第三次通过教科书时,我才理解 IP 碎片和 UDP 丢失之间的区别。 (10认同)

rep*_*lay 20

你不能确定他们真的立刻到达。如果 TCP/UDP 下方的数据链路层愿意,它们可能会将您的数据包拆分。特别是如果您通过 Internet 或您无法控制的任何网络发送数据,则很难预测。

但是无论数据是以一个数据包还是多个数据包的形式到达接收器。操作系统应该对这些数据包的串联进行抽象,因此对于您的应用程序来说,它仍然看起来像所有的东西都是一次性到达的。因此,除非您是内核黑客,否则在大多数情况下,您不必担心这些数据是在一个还是多个数据包中传输的。

对于 UDP,操作系统也会做一些抽象,因此接收数据的应用程序不必知道数据已经传输了多少个数据包。但与 TCP 不同的是,无法保证数据实际到达。数据也有可能被分成多个数据包,其中一些到达,有些没有。对于接收应用程序,不管它是否完整,它看起来都像是一个数据流。

  • @Hallucynogenyc:除非情况发生变化,否则 Internet 协议旨在允许超过 576 字节的数据包在旅途中的任何一点被拆分,但除了最终接收者之外,别无他求。我认为这个想法是在大多数情况下使用更大的数据包是为了减少开销;一旦数据包在其旅程的某个时刻被拆分,开销就已经产生,因此在最终接收方之前重新组合不会有任何帮助,如果必须重新拆分可能会受到伤害。 (2认同)

小智 18

例子。连续字符块对应于 send() 调用:

TCP:

Send: AA BBBB CCC DDDDDD E         Recv: A ABB B BCC CDDD DDDE
Run Code Online (Sandbox Code Playgroud)

所有发送的数据都是按顺序接收的,但不一定在相同的块中。

数据传输协议:

Send: AA BBBB CCC DDDDDD E         Recv: CCC AA E
Run Code Online (Sandbox Code Playgroud)

数据不一定按相同顺序排列,也不一定完全收到,但消息会完整保留。


小智 6

例如:如果我使用 TCP 协议发送 20 个字节,我能否 100% 确定我将一次接收 20 个字节,而不是 10 个字节然后再接收 10 个字节左右?

不,TCP 是一种流协议,它按顺序保存数据,但不会按消息对其进行分组。另一方面,UDP 是面向消息的,但不可靠。SCTP具有两全其美的优点,但由于 NAT 破坏了 Internet,因此无法在本机使用。