理解TCP数据包大小限制与UDP数据包大小限制及其在boost::asio编程层面上的含义

3

我正在使用boost::asio在客户端应用程序和服务器应用程序中进行UDPTCP通信。我发现我只能使用UDP传输大小为65535字节的数据,因为这似乎是UDP中的最大包大小。

TCP中也存在最大包大小限制,即65535字节?但是我可以使用boost::asio::writeTCP中发送大于最大包大小的块,并且在客户端应用程序上全部读取它。我发现在TCP中我不必担心最大包大小,但在UDP中,我必须确保每个socket.send_to都使用小于最大包大小的缓冲区。

这是如何工作的?这是因为TCP是基于流的,负责在较低层创建数据包吗? 是否有办法增加UDP中的最大包大小

我从服务器端发送的UDP数据包中的某些字节可能会在客户端读取时丢失吗?如果是,则是否有一种方法仅在UDP的客户端侧检测到丢失?

2个回答

3
TCP负责传输控制(实际上在TCP中,T和C就代表传输控制)。通常情况下,您不必担心发送到TCP套接字的数据量,因为它可以自行管理每个数据包发送的数据量。每个TCP数据包最多可以有65536字节的有效载荷,但通常您不需要考虑这一点,因为TCP相当复杂,可以完成许多任务。
UDP缺乏任何控制机制,并尽可能保持简单,因此您需要决定每个数据包发送多少数据。最大大小再次为65536字节,因为UDP头部只有两个字节用于指定消息的长度。在确定UDP数据包大小时,还要考虑底层协议也有其自己的限制(IP为65K,以太网为约1500字节)。
您无法增加UDP数据包的最大大小,通常也不希望这样做,因为大型UDP数据包可能会被丢弃而没有任何通知。其他SO上的答案建议在互联网上使用512-8K数据包进行数据报传输。

UDP数据报可能会损坏一些字节(但不是“丢失”)。但每个数据包都有一个校验和来覆盖,因此客户端将知道数据报在传输过程中是否已经损坏。


如何使用boost::asio UDP进行基于校验和的检查?如果可以,请提供建议。 - TheWaterProgrammer
@AdaLovelace,你不需要对此做任何处理,校验和已经是UDP协议的一部分。你已经有了这个检查。 - u354356007
1
请注意,IPv4中的校验和是可选的。但是,如果收到数据包,则还必须通过以太网校验和。 - Jonas

3
问题与UDPTCP关系不大,而与IP有关。 UDPTCP是传输协议,没有定义最大数据包(或段)大小。 IP是网络协议。一个IP数据包最多可以包含65536(2^16)字节,因为有两个字节用于定义数据包大小。 大的IP数据包被分成多个段。如果其中一个段丢失或损坏,则整个IP数据包都将丢失。段的大小取决于链路层协议,通常是以太网。对于以太网,最常见的最大大小是1500字节,或者如果允许使用巨型帧,则更大。
因此,如果您传输大于1500字节的UDP数据包,则可能会被分成几个段。如果网络上没有丢失,则通常情况下这没问题。但是,如果存在丢失,当有更多依赖段时,影响只会变得更大。例如,考虑一个丢失率为1%的网络,如果您传输65536字节的UDP数据包,则它很可能会被分成44个段。那么这个数据包被接收的概率是:(1-0.01)^44 = 64%...
这也是为什么许多TCP实现和基于UDP的应用程序最多使用1500字节数据包的原因。
提取损坏的数据包是一项非常棘手的任务,请寻找像libpcap这样的库。

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