阻止 UDP 数据包在接收缓冲区快满时被部分截断

Stopping UDP packets from being partially chopped off when receive buffer is almost full

我正在为一项作业在 C++ 中实现滑动 window 协议。我正在使用 UDP (SOCK_DGRAM) 套接字。有时,程序必须背靠背发送大量数据包(与 window 一样大)。到目前为止,我还没有将 window 大小增加到超过 30,但它最终应该能够达到 256。数据包大小必须从用户输入中获取,因此它可以是任何合理的。当数据包较小时,如 512 字节,则没有问题。当数据包较大时,如 40KB,前几个数据包被正确读取,然后突然我的 readNBytes() 函数在只读取其中一个数据包的一部分后挂起。我假设操作系统的接收缓冲区正在被填充,并且其中一个数据包的那部分被丢弃。读取进入缓冲区的部分,然后 readNBytes() 正在等待其余部分,这些部分被 OS.

丢弃

发生这种情况时,是否有 OS 设置的标志供我阅读?理想情况下,如果 OS 不适合接收缓冲区,我想强制丢弃整个数据包,而不是只接收其中的一部分。 IP_DONTFRAG 在我的系统上没有定义,所以我不知道该怎么做。我还会想出一种方法,使接收缓冲区大小成为我的数据包大小的倍数,这样数据包就不能部分放入缓冲区。克服这个问题的最佳方法是什么?

如果您的 recv() 缓冲区对于数据报来说太小,它将被截断。不会造成阻塞。

您的数据报太大了。 IPv4 限制为 65507 字节,但普遍接受的实际限制为 534 字节。您当然应该将它们保持在路径 MTU 下,否则您会保证碎片化,这只会增加数据报丢失的机会。

OS 不会将半个数据包传递给应用程序。

在发送端处理分段是 IP 的责任,IP 数据包最大可达 64K,并且将由 IP 分段以适应底层的 MTU。

在接收端发生相反的情况,重新组装。使用 UDP,您要么接收到整个数据包,要么什么也接收不到。 只接收其中一部分的唯一原因可能是您的应用程序接收缓冲区很小。一些套接字实现将其删除,即使所有内容都已收到