【问题标题】:Efficiently send a stream of UDP packets高效发送 UDP 数据包流
【发布时间】:2015-04-24 23:19:37
【问题描述】:

我知道如何在 C++ 中打开一个 UDP 套接字,我也知道如何通过它发送数据包。当我发送一个数据包时,我在另一端正确接收到它,一切正常。

编辑:我还建立了一个完整的确认系统:数据包被编号、校验和和确认,所以我随时知道我发送了多少个数据包,比如说,在最后一秒实际上是从另一个端点收到的。现在,我发送的数据只有在收到所有数据包时才可读,所以我真的不关心数据包的顺序:我只需要它们都到达,这样它们就可以随机序列到达,它仍然会没关系,因为按顺序排列它们仍然没有用。

现在,我必须传输一大块数据(比如 1 GB),我需要尽可能快地传输它。所以我将数据分成 512 字节的块并通过 UDP 套接字发送。

现在,由于 UDP 是无连接的,它显然不提供任何速度或传输效率诊断。因此,如果我只是尝试通过我的套接字发送大量数据包,我的套接字只会接受它们,然后它们将被一次性发送,我的路由器将发送第一对,然后开始丢弃它们。所以这不是完成这项工作的最有效方法。

我当时做的是制作一个循环:

  • 睡一会儿
  • 发送一堆数据包
  • 再睡觉等等

我尝试进行一些校准,并获得了相当不错的传输速率,但是我有一个线程连续发送小束数据包,但我对间隔应该是什么以及数据包的大小只有一个实验性的想法应该是一堆。原则上,我可以想象,睡眠非常短的时间,然后一次只发送一个数据包将是路由器的最佳解决方案,但是在 CPU 性能方面完全不可行(我可能需要忙等待,因为两个连续数据包之间的时间会非常小)。

那么还有其他解决方案吗?任何被广泛接受的解决方案?我假设我的路由器有一个缓冲区或类似的东西,因此它可以一次接受一些数据包,然后需要一些时间来处理它们。缓冲区有多大?

我不是这方面的专家,所以任何解释都会很棒。

但是请注意,由于技术原因,根本没有办法我可以使用 TCP。

【问题讨论】:

  • 开始使用iperf。看看你离 iperf 的速度还有多远。它是开源的,所以你可以看到他们做了什么。
  • 嗯..也许你需要某种流控制协议。您可以将其基于对等方返回的 ACK 消息,以便在总体损失超过某个值时降低数据报发送速率。这么小的 512 字节的数据报似乎效率不高:(
  • 你有没有想过让你的套接字SOCK_SEQPACKET
  • @MartinJames 我也想过做这样的事情!我认为我可以做一个固定的时间步长(比如 0.01 秒),然后在每一步发送可变数量的数据包。但我不确定如何确定最佳步骤!
  • 如果你不能使用 TCP,你仍然可以阅读 TCP 的流量控制功能是如何工作的,也许从中获得一些关于如何做类似事情的想法。

标签: c++ sockets networking udp


【解决方案1】:

正如在其他一些 cmets 中提到的,您所描述的是一个流量控制系统。维基百科文章很好地概述了执行此操作的各种方法:

http://en.wikipedia.org/wiki/Flow_control_%28data%29

您现有的解决方案(在数据包组之间休眠一段硬编码时间)原则上可行,但为了在实际系统中获得合理的性能,您需要能够对变化做出反应网络。这意味着实现某种反馈,您可以根据网络特性(例如吞吐量和丢包率)自动调整传出数据速率和数据包大小。

执行此操作的一种简单方法是使用重新传输的数据包数量作为流量控制系统的输入。基本思想是,当您有大量重新传输的数据包时,您将减小数据包大小,降低数据速率,或两者兼而有之。如果您有很少的重传数据包,您将增加数据包大小和数据速率,直到您看到重传数据包的增加。

这有点过于简单化了,但我想你明白了。

【讨论】:

  • 好!其实,我已经做过这样的事情了。我发送的数据包经过校验和,它们得到确认,而且我还知道我在最后半秒内发送了多少数据包实际上被另一个端点接收到。现在,我考虑改变每次调用 dispatch() 函数时发送的数据包数量。但是我应该多久调用一次呢? K 是我每秒调用它的次数,D 是我每次调用它时发送的数据包数。是N每秒的数据包数,那么N = K * D。但是我想效率也取决于D,对吧?
  • 我的意思是,假设我想每秒发送 1000 个数据包。我想睡一秒,发送 1000 个数据包,然后再睡一秒与睡一毫秒,发送一个数据包,然后再次睡眠是不一样的。但是对于非常高的 N,保持 D = 1 并增加 K 变得不可行。
  • 此外,我什至不确定我应该使用什么范式睡眠-发送-睡眠-发送。也许有一些我一无所知的预构建解决方案?
  • 啊,好吧。因此,您已经拥有可靠的运输,并且您正在寻找最佳效率。您可以在问题中明确说明。
猜你喜欢
  • 2013-09-15
  • 1970-01-01
  • 2012-12-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-04-25
  • 2011-02-07
  • 2012-10-03
相关资源
最近更新 更多