UDP 数据包可以像 TCP 一样部分发送吗?

Can UDP packets be partially sent like TCP ones?

我创建了某种类型的 client/server 应用程序,它有自己的数据 ACK 系统。由于一些限制,它最初是用 TCP 编写的,但是基础是在考虑 UDP 的情况下编写的。

我发送到服务器的数据包有自己的封装(数据包ID和数据包大小headers。我知道UDP也有校验和所以我没有添加header为此),但是 TCP 是如何工作的,我知道服务器可能不会收到整个数据包,所以我收集并缓冲了收到的数据,直到收到完整的有效数据包。

现在我有机会将我的 client/server 程序更改为 UDP,而且我知道与 TCP 的一个区别是数据的接收顺序与发送顺序不同(这就是我添加数据包的原因编号 header).

我想知道的是:如果我发送多个数据包,是否会在没有保证顺序但有保证封装的情况下收到它们?我的意思是,如果我稍后发送一个大小为 1000 字节的数据包和另一个大小为 400 字节的数据包,服务器会收到 2 个数据包,一个 1000 字节,另一个 400 字节,还是有机会接收 200 个那 1000 个字节,然后是那 1000 个字节中的 400 个字节,然后像 TCP 那样处理其余的字节?

UDP 是一种数据报服务。数据报可能会被拆分以进行传输,但在传递到应用程序层之前它们将被重新组合。

对于较小的数据包,您不必担心数据包会被分成多个数据包。这通常只是数据包通过以太网时的问题。

你问“服务器是否会收到 2 个数据包,一个 1000 字节,另一个 400 字节,或者有机会接收 1000 字节中的 200 个,然后是 1000 字节中的 400 个字节之后剩下的字节像TCP一样可以做吗?

对于小于 1492 字节的数据包,不会有任何部分数据包。

更新:
显然我认为有必要澄清为什么我说 UDP 数据包长度为 1492 字节或更短不会影响传输稳健性。

RFC 768 中隐式指定的最大 UDP 长度为 65535,包括 8 个字节 Header。最大有效载荷帧长度为 65527 字节。

虽然这不应该是有争议的数字,但 UDP 数据长度经常被错误地报告。这在之前的 post:

中得到了例证

What is the largest Safe UDP Packet Size on the Internet

数据包不受底层网络 ToS 的 MTU 或通信协议的帧长度(例如分别为 IP 和以太网)的约束。 MTU 和协议长度之间的差异通过分段和重组来弥补

在传输层,每个网络服务类型 (ToS) 都有一个特定的最大传输单元 (MTU)。 UDP 封装在 IP 数据包中,IP 数据包由传输网络的 ToS 封装。 IP数据包通常通过各种ToS的网络传输,包括Ethernet、PPP、HDLC和ADCCP。

当接收网络 ToS 的 MTU 小于发送 ToS 时,接收网络必须对接收到的数据包进行分段。当网络将数据包发送到具有更高 MTU 的网络时,接收网络必须重新组装任何碎片数据包。

以太网是MTU最低的事实上的主流协议。 Non-Mainsteam Arcnet 的MTU 是507 字节。实际的最低 MTU 是以太网的 1500 字节,减去开销后最大负载长度为 1492 字节。

如果 UDP 数据包超过 1492 字节,则数据包可能会被分段并重新组装。 Fragment and Reassembly 增加了耦合 UDP 和 IP 的复杂过程的复杂性,因此应该避免。

因为 UDP 是一种 non-guaranteed 数据报传送协议,它提高了传输性能。健壮性留给发起和终止应用程序。 RFC 1166 为通信协议 link 层、IP 层和传输层制定了标准,UDP Application 负责打包、重组和流量控制。

最大 UDP 数据包大小也可以通过通信主机的应用层来降低。数据包长度是性能和健壮性之间的平衡。

通信主机的应用层可以设置最大 UDP 数据包大小。应用层的典型 UDP 最大数据长度将使用 IP 协议或主机数据 Link 层允许的最大值,通常是以太网。

是应用程序的程序员选择使用主机应用层或主机数据Link层。主机应用层将检测 UDP 数据包错误并在必要时丢弃该数据包。当应用程序直接与主机数据通信时 Link,应用程序便负责检测数据包错误。

使用以太网最大负载长度1492字节的最大UDP数据包长度将消除多帧的分段和传递顺序问题。

这就是为什么我说数据包长度不是数据包长度为 1000 和 400 字节的碎片问题。

###

我不知道你说的"guaranteed encapsulation"是什么意思,对我来说没有意义。

对于 IP,无论是 UDP 还是 TCP,都无法保证数据包按顺序交付。

只要控制对话双方,就可以在数据包中制定自己的协议来处理排序和 post 数据包。保留数据包的前 x 个字节用于顺序编号和数据包总数。 (例如,3 个中的 1 个、2 个中的 2 个、3 个中的 3 个)。如果客户端丢失了数据包,则客户端必须发送重传请求。您需要确定要达到的数据完整性级别。就像 re-transmission 数据包丢失了一样。

这可能就是您所说的 "guaranteed encapsulation",您的数据报包中还有其他信息以确保某些完整性。如果分成多个数据报,您应该为发送的总数据添加自己的 CRC。校验和不是很可靠,仅适用于一个数据包。

UDP 比 TCP 快得多,但 TCP 具有流量控制和保证传送。

UDP 适用于流媒体内容,如丢失数据包无关紧要的语音。

自从这些问题成为主要问题以来,网络可靠性有了很大改善。