接收UDP数据包

9
假设我的程序通过网络(UDP)发送了1000字节。接收者是否确保能够一次性接收到这1000字节?或者他需要进行多次“读取”才能接收完整的消息?如果后者是真的,如何确保同一消息的数据包顺序不会被“混淆”(按顺序)?或者协议是否保证了顺序?
编辑:也就是说,我的消息是否可能被分成几个数据包?(如果尝试发送10000mb的消息,会发生什么?)
5个回答

13

你要么全部接收,要么全部不接收。

但是不能保证你会按照传输的顺序精确地接收数据包;数据包丢失、重新排序和(较少发生的)重复都是有可能的。

有一个最大帧大小限制(为 65,507 字节),如果发送的数据包超过这个大小就会返回错误。

必须提供足够的缓冲区以便在一次调用中接收整个数据包。

UDP 数据包可以被分成多个 IP 片段,但操作系统将丢弃不完整的数据包。因此,这对应用程序来说是透明的。


4
接收者将在一个调用中获得整个数据包。即使在理论中,数据包长度也是有限制的:

长度 一个16位字段,指定整个数据报(标头和数据)的字节长度。最小长度为8个字节,因为这是标头的长度。该字段大小设置了UDP数据报的理论极限为65,535个字节(8字节标头+65527字节数据)。由底层IPv4协议强制实施的数据长度的实际限制为65,507字节。

但是实际限制要低得多,通常可以安全地假设为512字节。请参见互联网上最大的安全UDP数据包大小是多少


如果我尝试发送1024字节,会发生什么?我会在发送时收到错误提示吗?还是我的消息会被分成不同的数据包发送?(并且它们之间的顺序会保持不变吗?) - unknown
512是最小的安全大小。1024可能会成功。或者在发送过程中出现错误。更糟糕的是,数据包可能会被某些路由器丢弃,而你却毫不知情。UDP没有分段和重组的功能,这就是TCP存在的意义。 - Remus Rusanu
3
Remus: 这是错误的。分段和重组是在 IP 层完成的,这意味着它适用于 UDP。对于 UDP,你将要么完整地看到正确组装的数据报,要么什么都不会看到。TCP 还增加了排序和确认/重传功能。 - caf
@caf:没错,但如果你使用的是有损网络,你的应用程序可能只能收到一半的数据包;如果你使用的是分段的UDP,那么即使是通过了的一半数据包也会丢失。 - Zan Lynx

2
UDP与TCP不同,它不是一种可靠的协议。它没有内置的机制来确保数据包按正确顺序到达,甚至有时可能会丢失。因此,你可以编写发送/接收例程,以锁步方式进行,每次发送数据包后,发送者必须等待接收确认(ACK)才能再次发送。如果在指定的超时时间内未收到ACK,则必须重新发送数据包。这样可以确保数据包按正确顺序到达。(更多信息,请查看使用此策略的TFTP协议的RFC文档RFC for the TFTP protocol。)
最后,如果可能,你可能需要考虑使用TCP。

1

使用UDP Lite,您可以请求接收部分损坏的数据包。这对于视频和VoIP服务非常有用。


希望我们能够得到一个Windows的实现,这样它就可以用于桌面端用户应用程序。 - mbx

1

使用UDP发送的数据被分组为数据包,因此如果您发送x个字节,则如果接收方接收到该数据包,则他将接收x个字节。

但是,您的数据包可能甚至不会到达,或者它们可能以错误的顺序到达。


但是程序是否可能先看到只有500字节可用,过一段时间后再接收另外的500字节呢? - unknown
如果我的消息大小为100万字节长,那该怎么办?(谢谢) - unknown
我猜它也可以处理一百万,但这并不推荐。 - Charles
1
长度字段是一个16位数字,因此64k减去IP和UDP头的空间是一个硬性限制。 - Grumdrig
那么,如果我尝试发送一个比这更大的消息会发生什么?我首先就无法发送它了吗? - unknown
然后,您应该将数据分成多个数据包发送;一旦您验证已接收到所有数据包,您可以迭代所有数据包并提取内容以重现原始文件。 - Charles

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