1

我正在编写一个程序,它将一个小的 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, ...
  }
}

有人知道这个问题吗?它从何而来?我该如何解决?
使用我的解决方法(添加睡眠),我如何计算正确的毫秒数?

4

1 回答 1

1

由于您标记为拥塞控制,我想您已经知道发生了什么……确实,数据包可能由于拥塞而被丢弃。由于您发送到许多目标,因此拥塞肯定会发生在您的网络一侧。问题是拥塞并不是真正确定的,所以你必须做出近似。

我知道在不丢弃数据包的情况下调节此类流量的一种技术是计算目标的延迟。如果您有许多目标,请计算已知良好服务器的延迟(即使它不是目标)。将会发生的是,当拥塞开始时,中间路由器的缓冲区将开始填满,这将显着增加延迟。当路由器的缓冲区已满时,将开始丢包。您必须做的是在检测到延迟增加时立即降低发送速率。

您可以从较低的发送速率开始并在延迟不变时增加,但请注意不要增加太快,否则丢包会发生得太快而无法做出反应(缓冲区填充得太快并在您减少之前丢弃数据包)。

一个问题是路由器的缓冲区越小,您必须做出反应的时间就越少(而且它可能太小而根本没有时间做出反应)。此外,如果拥塞实际上更多地偏向某些目标(如果某些目标被分组在瓶颈后面),则此技术将无济于事。

TCP 中使用的另一种常见技术是在检测到数据包丢失时重新传输并降低发送速率。这意味着您需要实现 ACK 并重新传输。这种技术更防弹,但依赖于丢包,因此效率较低。

您还可以实施这两种技术(例如:使用延迟进行调节,如果仍然发生丢失则重新传输)以改进结果(更有效但仍然是防弹的)。

于 2015-03-04T11:48:18.817 回答