当接收缓冲区几乎满时,阻止UDP数据包被部分截断
Stopping UDP packets from being partially chopped off when receive buffer is almost full
我正在用C++实现一个赋值的滑动窗口协议。我正在使用UDP(SOCK_DGRAM)套接字。有时,程序必须背靠背地发送大量数据包(与窗口大小一样大)。到目前为止,我还没有将窗口大小增加到30以上,但最终应该能够达到256。数据包大小必须取自用户输入,因此它可以是任何合理的大小。当数据包的大小很小,比如512字节时,就没有问题。当数据包大小较大时,如40KB,前几个数据包被正确读取,然后我的readNBytes()函数在只读取了其中一个数据包的一部分后突然挂起。我假设操作系统的接收缓冲区正在被填充,其中一个包的那部分被丢弃。进入缓冲区的部分被读取,然后readNBytes()正在等待其余部分,这些部分被OS丢弃。
当这种情况发生时,操作系统是否设置了任何标志供我读取?理想情况下,如果数据包不适合接收缓冲区,我想强制操作系统丢弃整个数据包,而不是只拿走其中的一部分。我的系统上没有定义IP_DONTFRAG,所以我不知道如何做到这一点。我还想找到一种方法,使接收缓冲区的大小是我的数据包大小的倍数,这样数据包就不能部分放入缓冲区。克服这个问题的最佳方法是什么?
操作系统不会向应用程序传递半个数据包。
IP负责处理发送端的碎片,IP数据包最高可达64K,并将按IP进行碎片处理,以适应底层的MTU。
在接收端则相反,重新组装。使用UDP,您要么接收整个数据包,要么什么都不接收只接收其中一部分的唯一原因可能是您的应用程序接收缓冲区很小。一些套接字实现将其截断,即使所有内容都已收到
如果recv()
缓冲区对于数据报来说太小,它将被截断。它不会造成阻塞。
你的数据报太大了。IPv4限制为65507字节,但通常接受的实际限制为534字节。您当然应该将它们保持在路径MTU下,否则您将保证碎片化,这只会增加数据报丢失的机会。
- boost::asio UDP 广播客户端仅接收"fast"数据包
- 发送固定大小的 UDP 数据包
- 使用C++将UDP数据包存储在Structure中
- 在高数据包速率下最大限度地减少丢弃的 UDP 数据包 (Windows 10)
- Qt 在可预测的秒数后跳过 UDP 数据包
- 高频接收UDP数据包:丢包?
- C++ 通过 UDP 发送数据包,但不接收数据包
- 为 posix recv 设置超时会导致 udp 数据包丢失吗?
- 了解 UDP 数据包大小限制的 TCP 数据包大小限制以及它在 boost::asio 编程级别的含义
- 获取进入UDP数据包的目标端口
- 操纵Windows Explorer窗口时,UDP数据包会掉落
- 如何模拟QT UDP程序的数据包丢失
- C++ 使用 recvmmsg 丢弃 UDP 数据包
- 使用 UDP 协议从 Windows 套接字发送到 Qt 套接字的网络数据包上的结构编码和解码
- 如何在QT中接收适当的UDP数据包
- 使用ASIO捕获大量UDP数据包
- 如何正确接收多播UDP数据包
- C++ - 构造带有标头的数据包并通过 UDP 套接字发送
- 通过RecvFrom(UDP)接收数据包的一部分
- 服务器未收到UDP数据包,花费数小时试图找出问题所在