我正在编写一个程序,它会将一个小的UDP数据包(大约100个字节)发送到很多目的地(包括一些真正的目的地,所有其他目的地都是伪目的地)。
如果我发送到少量目的地,真实目的地可以收到数据包。
如果我在每次发送之间没有睡眠的情况下发送到大量目的地,则只能接收一些真实目的地或者所有目的地都无法接收数据包。
如果我在每次发送之间发送一个具有正确睡眠的大量目的地,则只能接收一些真实目的地或者所有目的地都无法接收该数据包。
这是示例代码:
void send()
{
//about 10K addresses
QList<QHostAddress> addrs; //include some real destinations and all others are fake destinations
quint16 port;
QString data("Data: about 100 bytes");
QUdpSocket udp;
for(QHostAddress add : addrs)
{
udp.writeDatagram(data.data(), add, port);
//QThread::msleep(1); // 1 milisecond or 10, 100, ...
}
}
有人知道这个问题吗?它从何而来?我怎么解决呢? 通过我的解决方法(添加睡眠),我如何计算正确的毫秒数?
答案 0 :(得分:1)
由于您标记为拥塞控制,我猜您已经知道发生了什么......实际上,数据包可能因拥塞而被丢弃。由于您发送到许多目标,拥塞肯定发生在您的网络一侧。问题是拥堵并不是确定性的,所以你必须做出近似值。
我知道在不丢弃数据包的情况下调节此类流量的一种技术是计算目标的延迟。如果您有许多目标,请计算已知良好服务器的延迟(即使它不是目标)。会发生什么,当拥塞开始时,中间路由器&#39;缓冲区将开始填充,并将显着增加延迟。当路由器&#39;缓冲区已满。您需要做的是在检测到延迟增加时立即降低发送速率。
您可以从较低的发送速率开始,并在延迟没有变化时增加,但要注意不要增加得太快,否则数据包丢失会发生得太快而无法做出反应(缓冲区填充速度过快而丢弃数据包之前你可以减少。)
一个问题是路由器越小&#39;缓冲区,你需要做出反应的时间越少(而且它可能太小而没有时间做出反应)。此外,如果拥塞实际上更多地放在某些目标的一侧(如果某些目标被分组在瓶颈后面),这种技术将无法提供帮助。
TCP中使用的另一种常见技术是在检测到数据包丢失时重新传输并降低发送速率。这意味着您需要实现ACK并重新传输。这种技术更具防弹性,但依赖于数据包丢失,因此效率较低。
您还可以实施这两种技术(例如:规则延迟,如果仍然发生丢失则重新传输)以改善结果(更高效但仍然是防弹)。