使用ASIO捕获大量UDP数据包

时间:2017-03-01 03:31:14

标签: c++ networking udp asio

我使用asio(非升级版)库通过10GB以太网适配器捕获传入的UDP数据包。 每秒150k包很好,但是当我达到300k包/秒的更高速率时,我开始丢弃数据包。

我非常确定瓶颈是在DMA中从网卡到主机系统的300k单独传输。传输不是每次传输只有1400字节,所以不是带宽问题。

理想情况下,我希望有一种机制可以将来自多个数据包的数据合并到一个到主机的DMA传输中。目前我正在使用asio :: receive来进行同步传输,它提供比async_receive更好的性能。

我尝试使用带有更大缓冲区的receive命令,或使用多个缓冲区的数组,但我似乎总是只读取1400字节。

有什么方法吗?

理想情况下,我想一次读取1400字节的一些倍数,只要它没有花费太长时间来填充总数。 即。等待4毫秒,然后返回4 x 1400字节,或者只是在4毫秒后返回,但是有多少字节可用...

我无法控制整个网络,所以我不能强制使用巨型帧:(

干杯,

2 个答案:

答案 0 :(得分:2)

我会删除asio图层并直接转到金属。

如果你在Linux上,你应该使用recvmmsg(2)而不是recvmsg()recvfrom(),因为它至少允许在内核中一次传输多个消息,其他人没有。

如果你不能做这些事情,你需要至少调整你的期望。 recvfrom()recvmsg()以及asio中的任何谎言都不会一次传递多个UDP数据报。你需要:

  • 尽可能加快接收循环,消除所有可能的开销,尤其是动态内存分配和其他套接字或文件的I / O.
  • 确保套接字接收缓冲区尽可能大,至少为兆字节,通过setsockopt()/SO_RCVBUFSIZ,并且不要假设你设置的是你得到的:通过getsockopt()获取它看看平台是否以某种方式限制了你。

答案 1 :(得分:1)

可能你可以使用libcap库http://www.tcpdump.org/尝试使用tcpdump进行workarround并过滤以重新接收UDP数据包