我有一个相对简单的服务器到多客户端设置。服务器使用多播发送数据报,(可能很多)客户端接收它们。
Linux(RHEL)客户端使用以下方式接收/读取这些数据报的大约3-4 Mbps流:
QByteArray datagram;
while (udpSocketReceiver->hasPendingDatagrams())
{
datagram.resize(udpSocketReceiver->pendingDatagramSize());
udpSocketReceiver->readDatagram(datagram.data(), datagram.size());
}
这似乎可能在99.99%的时间内起作用。但是,我偶尔会看到数据报丢失(正如我正在使用的内部计数器/架构所观察到的那样)。我的第一个想法是“好吧,它是UDP - 它必须在传输中被丢弃。”
然而,我也在使用tcpdump监视客户端/接收方...并且我也看到那里存在的“丢失”数据报,应用程序错过了这些数据报。似乎错过的数据报正在被网络接口接收,但我偶尔会将它们放入应用程序层。几乎是我希望放弃它们的最后一个地方。
我一直在调整Linux中的适用缓冲区(net.core.rmem_max,net.core.rmem_default),但没有任何运气。
感谢您的帮助。
答案 0 :(得分:0)
这是正常行为!即使您看到UDP数据包到达您的计算机物理层,也不意味着应用程序肯定会收到它...由于缓冲限制..或CPU,内存瓶颈。 / p>
在三个可能的传输时隙中丢弃UDP数据包:
发件人缓冲区 在每个UDP套接字上,都有一个发送缓冲区对数据包进行排队。系统尽可能快地获取和发送数据包,但是如果你的网络接口速度很慢或者时隙不足以100%有效地处理队列,那么它可能无法像以前那样快速地发送数据包。你把它们放进去了!在这种情况下,一些包被简单地丢弃。 More reading
网络丢失数据包
即使发送方在(公共)网络中成功发送UDP数据包,它仍然可能在此过程中丢失。为什么:路由算法很复杂..路上的一切都在缓冲区和优先级基础上工作..在该网络之上并不是100%可靠..由于校验和错误等原因可能导致分组数据丢失。
接收缓冲区 UDP数据包可能会到达接收方物理层。但应用程序正在侦听并等待带有套接字的数据包接收缓冲区。那个缓冲区的大小会导致丢失吗?如果应用程序无法以它们排队的速率处理所有缓冲区,则缓冲区可能会溢出并且丢弃数据包Further reading这可以帮助设置接收器缓冲区。