从接口 c++ 读取原始数据的最快方法

fastest way to read raw data from interface c++

这里是主要问题。

  1. 我有 10G 以太网接口,当前流量为 6-7 Gbit/sec
  2. 我需要实施防火墙然后我需要捕获原始数据包来过滤一些数据包。
  3. 简单地说,我开始实现作为原始套接字的必要代码如下。绑定到特定接口的套接字。

    socketfd=socket(AF_PACKET,SOCK_RAW,htons(ETH_P_ALL));
    strncpy(ifopts.ifr_name,interfaceName,IFNAMSIZ-1);
    ioctl(socketfd,SIOCGIFINDEX,&ifopts);
    sll.sll_family=AF_INET;
    sll.sll_ifindex=ifopts.ifr_ifindex;
    sll.sll_protocol=htons(ETH_PALL);
    bind(socketfd,&sll,sizeof(sll));
    
  4. 这是我的阅读方式,mtu 大小是 9000

    while(true)
    recvfrom(socketfd,buffer,9000,0,0,0);
    
  5. 没有对数据包进行任何处理,我得到了 ~150Mbit/sec。

这是我需要解决的问题。我意识到 nload 或 ip -s link 显示实际速率;但我无法在 6-7Gbit/sec.

左右达到这些数字

~150Mbit/sec 对我来说太荒谬了。我需要尽可能多地提高性能,使用一个 CPU。我会尝试使用 PF_INET,如果你愿意,我可以分享它的结果。

答案在这里。

  • 首先抓包速度不仅取决于接口上的字节大小,包的数量也很重要。所以socket编程也受到数据包数量的限制。我测量为每秒 20 万个数据包 (pps)。
  • 使用更好的网络驱动程序是提高pps的一种方法。 PF_RING 是可能的库和驱动程序。您可以使用试用版进行测试。我只是在我的网络上测试它,结果是 14M pps。那么这个速率差不多是10Gbit/sec。这就是我所经历的。

谢谢大家