UDP数据包是否能像TCP一样部分发送?

7

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

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

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

我想知道的是:如果我发送多个数据包,它们是否会按照保证的封装顺序而无序接收?我的意思是,如果我发送一个1000字节大小的数据包,然后稍后发送一个400字节大小的数据包,服务器是否会接收到2个数据包,一个1000字节和另一个400字节,或者有可能像TCP那样先接收到1000字节中的200字节,然后接收到1000字节中的400字节,最后再接收到剩余的字节?


你真的不应该使用“数据包”这个词来指代那么多不同的东西。可能会在任意数量的数据包中发送的协议数据单元应该被称为“消息”。 - David Schwartz
1
在应用层,我称它们为数据包,在任何地方(包括维基百科)阅读时,人们都是这样理解的。当他们谈论传输层并且必须区分消息和数据包时,我看到他们也谈论消息。 - Jorge Fuentes González
计算机科学中数据包的定义是:“在互联网或任何其他分组交换网络上,在源和目的地之间路由的数据单元。”虽然有时候这个词被用来表示其他意思,但当你谈论涉及实际数据包的系统时,使用同一个词来表示两个完全不同的事情会导致混淆。 - David Schwartz
2个回答

18

UDP是一种数据报服务。数据报可能会在传输过程中被分割,但在传递到应用层之前会被重新组装。


就是我想要的。谢谢你。 - Jorge Fuentes González

2
使用小数据包时,您不必担心数据包会被分成多个数据包。这通常只在数据包超过以太网网络时才是问题。
您问:“服务器是否会收到两个数据包,一个1000字节,另一个400字节,或者有可能接收到1000字节的200字节,然后1000字节的400字节,最后再接收其余的字节,就像TCP一样?”
如果数据包大小小于1492字节,则不会出现部分数据包。
更新:
显然,我需要澄清为什么我说UDP数据包长度小于1492字节不会影响传输的鲁棒性。
根据RFC 768隐含规定,UDP数据包的最大长度为65535字节,包括8字节的头部。最大有效载荷帧长度为65527字节。
虽然这个数字不应该有争议,但UDP数据长度经常报告错误。这在以前的帖子中得到了证明:
互联网上最大的安全UDP数据包大小是多少?
数据包不受底层网络的MTU或通信协议帧长度(例如IP和以太网)的限制。MTU和协议长度之间的差异通过分段和重组来解决。
在传输层,每种网络服务类型(ToS)都有特定的最大传输单元(MTU)。UDP被封装在IP数据包中,而IP数据包则由传输网络的ToS进行封装。IP数据包经常通过各种ToS的网络进行传输,包括以太网、PPP、HDLC和ADCCP。
当接收网络的MTU小于发送ToS时,接收网络必须对接收到的数据包进行分段。当网络向具有更高MTU的网络发送数据包时,接收网络必须重新组装任何分段的数据包。
以太网是事实上的主流协议,其MTU最低。非主流Arcnet的MTU为507字节。实际最低MTU是以太网的1500字节,减去开销后最大有效载荷长度为1492字节。
如果UDP数据包超过1492字节,数据包很可能会被分段和重组。分段和重组增加了已经复杂的UDP和IP耦合过程的复杂性,因此应该避免使用。
由于UDP是一种非保证的数据报传递协议,它提高了传输性能。健壮性留给源和终止应用程序。RFC 1166为通信协议链路层、IP层和传输层设置了标准,UDP应用程序负责数据包化、重组和流量控制。
通信主机的应用层也可以降低最大UDP数据包大小。数据包长度在性能和健壮性之间取得平衡。
通信主机的应用层可以设置最大UDP数据包大小。应用层的典型UDP最大数据长度将使用IP协议或主机数据链路层允许的最大长度,通常是以太网。
是应用程序员选择使用主机应用层还是主机数据链路层。主机应用层将检测UDP数据包错误并在必要时丢弃数据包。当应用程序直接与主机数据链路通信时,应用程序则有责任检测数据包错误。
使用以太网最大有效载荷长度1492字节的最大UDP数据包长度将消除多帧分段和传递顺序问题。
这就是我说1000和400字节的数据包长度不是分段问题的原因。

###

我不知道你所说的“guaranteed encapsulation”是什么意思,对我来说毫无意义。
使用IP时,无论是UDP还是TCP,都不能保证数据包的顺序和传递。
只要你控制对话的双方,就可以在数据包中制定自己的协议以处理排序和后续数据包。将数据包的前x个字节保留为顺序编号和数据包总数。(例如:1 of 3,2 of 2,3 of 3)。如果客户端缺少一个数据包,则必须发送重新传输请求。您需要确定要为数据完整性提供到哪个级别。例如,重新传输数据包也可能会丢失。
这可能就是你所说的“guaranteed encapsulation”,在数据报文中有其他信息以确保一定的完整性。如果将其分成多个数据报文,则应为发送的所有数据添加自己的CRC。校验和不够强大,仅适用于一个数据包。
UDP比TCP快得多,但TCP具有流量控制和保证传递的功能。
UDP适用于流媒体内容(如语音),其中丢失一个数据包并不重要。
自从这些问题成为主要关注点以来,网络可靠性已经有了很大的提高。

我所说的“保证封装”是指数据包分割,确保我的程序能够完整接收整个数据包,而无需缓冲直到整个数据包被接收。我已经开发了自己的功能排序协议,所以这部分没问题。你提到了部分数据包,那么这些数据包会在接收到整个数据包之前被传递到我的程序吗?编辑:我没有给你的回答投反对票。 - Jorge Fuentes González
UDP不需要应用层。根据您描述的方式,我假设您正在传输层构建自己的UDP数据报,绕过任何应用层(最高层)所在的主机层。 我的专业知识在数据链路层,在那里我为IBM,GE,GM和Ungerman Bass在20世纪80年代设计了MAC层IC。 最近大约15年前,我使用Atmel微控制器创建了一个UDP服务器。因无知而导致的反对票。在80年代,我是一名电子工程师,专门从事语音和数据网络技术。 - Misunderstood
不,我给你的踩是因为你并没有真正回答问题,而是发布了很多无关的信息,这个错误在你的评论中也重复出现了。 - user207421
@EJP 我已经更新了我的答案,并引用了一篇文章,其中您错误地评论了有关MS Windows 2000应用程序层Getsockopt()的答案,其中MS指定了其最大数据包长度为65507字节。您说:“Microsoft链接不是规范性参考。RFC是规范性参考;而您引用的内容仅适用于IPv4。” RFC768隐含地指定了UDP的最大长度为65527字节。IPv4和IPv6不能限制通信协议的最大长度,而必须分段较大的数据包长度,因此不适用于该答案。 - Misunderstood
请注意,长度为1484的名称称为MSS(最大分段大小),与MTU(最大传输单元)相对。 - Alexis Wilke
显示剩余5条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接