c++ - 使用ASIO捕获大量UDP数据包

标签 c++ networking udp asio

我正在使用 asio(非 boost 版本)库通过 10GB 以太网适配器捕获传入的 UDP 数据包。 每秒 150k 数据包就可以了,但当我达到每秒 300k 数据包等更高速率时,我开始丢包。

我非常确定瓶颈在于从网卡到主机系统的 DMA 300k 单独传输。传输量不大,每次传输仅 1400 字节,因此不是带宽问题。

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

我尝试过使用具有更大缓冲区的接收命令,或使用多个缓冲区的数组,但我似乎总是获得 1400 字节的单次读取。

有什么办法可以解决这个问题吗?

理想情况下,我想一次读取 1400 字节的倍数,只要填充总数不会花费太长时间。 IE。等待最多 4 毫秒,然后返回 4 x 1400 字节,或者在 4 毫秒后返回,无论有多少字节可用...

我不控制整个网络,因此我无法强制使用巨型帧:(

干杯,

最佳答案

我会移除 asio 层并直接接触金属。

如果您使用的是 Linux,则应该使用 recvmmsg(2)而不是 recvmsg()recvfrom(),因为它至少允许在内核中一次传输多个消息的可能性,而其他方法则不允许。

如果你不能做到这两件事,你至少需要降低你的期望。 recvfrom()recvmsg() 以及 asio 中位于它们之上的任何内容都不会一次传送多个 UDP 数据报。您需要:

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

关于c++ - 使用ASIO捕获大量UDP数据包,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42522662/

相关文章:

c++ - "compares less than 0"是什么意思?

visual-studio-2010 - Visual Studio 远程调试 Amazon EC2 机器

c++ - "open"对于接受者来说意味着什么?

tcp - 什么是正确的网络协议(protocol)用于偶尔从计算机A到B传输整数,具有最低的延迟?

java - 接收数据报包

c - 从 UDP 端口接收以太网帧

c++ - 在程序中一起使用 getline 和 strtok 的问题

c++ - 如何跳过基于范围的 for 循环的第一次迭代?

c++ - 使用正则表达式和 sed 命令替换 C++ 代码中的 ' *' 指针不起作用

android - 如何检查 Android 设备上的电话网络