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

Posted

技术标签:

【中文标题】UDP数据包可以像TCP一样部分发送吗?【英文标题】:Can UDP packets be partially sent like TCP ones? 【发布时间】:2015-04-02 02:21:57 【问题描述】:

我创建了某种类型的客户端/服务器应用程序,它有自己的数据 ACK 系统。由于一些限制,它最初是用 TCP 编写的,但基础是考虑 UDP 编写的。

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

现在我有机会将我的客户端/服务器程序更改为 UDP,并且我知道与 TCP 的一个区别是接收数据的顺序与发送的顺序不同(这就是我添加数据包 ID 标头的原因)。

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

【问题讨论】:

你真的不应该用“数据包”这个词来指代这么多不同的东西。可以在任意数量的数据包中发送的协议数据单元应称为“消息”。 嗯,我在应用层称它们为数据包,而且,正如我在任何地方(包括 wiki)所阅读的那样,人们在这一层谈论它们时就是这样理解它们的。我看到他们在谈论消息时也谈论传输层并且必须区分消息和数据包。 计算机科学对数据包的定义是“在 Internet 或任何其他数据包交换网络上的起点和终点之间路由的数据单元。”确实,这个词有时被用来表示其他东西,但是当你谈论涉及实际数据包的系统时,使用同一个词来表示两个完全不同的东西会引起混淆。 【参考方案1】:

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

【讨论】:

正是我想要的。谢谢。【参考方案2】:

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

你问”服务器会收到 2 个数据包,一个是 1000 字节,另一个是 400 字节,还是有机会收到 1000 字节中的 200 个,然后是 1000 字节中的 400 个字节,然后是其余的像 TCP 这样的字节可以做多少?

如果数据包大小小于 1492 字节,则不会有任何部分数据包。

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

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

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

What is the largest Safe UDP Packet Size on the Internet

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

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

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

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

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

因为 UDP 是一种无保证的数据报传送协议,它提高了传输性能。鲁棒性留给发起和终止的应用程序。 RFC 1166 为通信协议链路层、IP 层和传输层设定了标准,UDP 应用程序负责打包、重组和流量控制。

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

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

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

使用以太网最大有效载荷长度为 1492 字节的最大 UDP 数据包长度将消除分片和多帧传送顺序的问题。

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

###

我不知道您所说的“保证封装”是什么意思,这对我来说毫无意义。

对于 IP,无论是 UDP 还是 TCP,都无法保证数据包的传递。

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

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

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

UDP 适用于流式传输内容,例如丢失数据包无关紧要的语音。

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

【讨论】:

在保证封装的情况下,我在谈论数据包分割,保证在我的程序中接收到整个数据包,而无需缓冲,直到接收到整个数据包。我已经使用了我自己的功能排序协议,所以这部分很好。您谈论部分数据包。这些数据包会在收到整个数据包之前传送到我的程序吗?编辑:反对票不是我的。 UDP 不需要应用层。您描述您正在做什么的方式我假设您在传输层构建自己的 UDP 数据报,绕过应用层(最高层)所在的任何主机层。我的专长是数据链路层,我为 802.3、802.4、802.5 和 802.6 设计了 ​​MAC 层 IC。早在 1980 年代为 IBM、GE、GM 和 Ungerman Bass 服务。最近,大约 15 年前,我创建了一个带有 Atmel 微控制器的 UDP 服务器。否决票是由于无知。在 80 年代,我是一名专注于语音和数据网络的 EE。 不,我的反对意见是因为您没有真正回答问题,而是发布了很多不相关的信息,您在评论中重复了这个错误。 @EJP 我没有回答什么? OP 询问是否有机会接收分成更小块的数据包。仅当数据包通过以太网路由并且数据包大于 1492 字节(某些以太网数据包的最大字节数)时才有可能。由于网络故障,这种情况很少见,但有可能。其余的与 OP 的封装方案有关。 在 UDP 中根本不可能。整个数据报要么到达应用程序,要么没有到达应用程序,不管它在途中发生了什么或没有发生什么。这就是他要问的问题,而这就是你没有回答的问题。

以上是关于UDP数据包可以像TCP一样部分发送吗?的主要内容,如果未能解决你的问题,请参考以下文章

TCP与UDP的区别

TCP与UDP的区别

我用udp发送一个16进制包,接收端怎么解析。

套接字编程,如果我写入的数据超过一个 TCP/UDP 数据包可以携带会怎样?

网络编程 之粘包问题使用socketserver实现并发

TCP和UDP知识总结