基于libpcap/npcap的FPGA高速网络数据采集 windows端

在上位机上采集FPGA发送的数据包,实时性要求高,包率>10kpps,带宽>1Gbps/s,如何实现数据接收处理,并减少丢包成为了问题的关键。libpcap成熟的库,能够实现该功能。
事先准备
检查网卡的配置选项,其中rss比较重要,设置了以后会降低网卡占用的cpu负载。还有MTU,如果FPGA发送的是包长度大于1500,需要注意修改一下配置。
在windows上安装最新版本的npcap,代替winpcap。代码使用的wpcap.dll
默认路径是:C:\Windows\System32\Npcap\wpcap.dll
在linux上安装libpcap,驱动层尝试使用pf-ring。

网卡抓包的原理
在自己的程序里数据流向是:
网卡-> 驱动->内核buff-> 用户态buff->你的代码
需要注意的是:这里采集的数据包是数据链路层的,和udp、tcp这些协议无关。
如果使用wireshak:
网卡->驱动/内核-> 硬盘(pcap格式)

问题:如何解决数据太快出现丢包问题,需要对每个环节进行优化?
系统级调优:看看电脑的配置是否太过时了,cpu、内存是否太老,cpu的超线程应该关了。
1. 网卡,网卡的性能可以进行优化,在linux中可以通过ethtool 配置。在windows上 打开网络适配器或者驱动程序进行查看。万兆网卡通常比千兆网卡的配置更好,如rss队列,缓冲区等,因此丢包率更低。
2. 驱动/内核 ,关键函数pcap_setbuff()。网卡数据第一次copy 进入ring buffer,ring buffer 是一块内存区域,在windows 中对应的是 NoPagePool,通过任务管理器可以进行查看,其大小可以通过 pcap_setbuff 设置,默认值为 1e6.需要注意的是ring buffer 满了后,数据包会被丢弃。如果因此导致的丢包,数量可以通过libpcap api查看。
3. 从驱动/内核到用户态 ,数据从kernel buffer 传输到了user buffer,进行了一次copy . copy的频率由pcap_setmintocopy 函数决定,默认值为16e3,也就是超过size 后,进行一次copy.如果为了最小化延迟,可以设置为0进行尝试,同时增加了CPU使用率。如果数据传输太快,导致cpu某个核占用达到100%,应当增加该值。
用户态缓冲区:user buffer,默认为256e3。如果代码部分读取太慢,也就pcap_loop()的callback 函数处理太慢,使得该缓冲区溢出,会导致丢包。可以适当进行增加调优,降低丢包率。
相关函数为:pcap_setuserbuffer() 返回为0则表示设置成功。
5.抓包函数具体实现为pcap_loop ,不要用pcap_next_ex 因为会多一次copy (官方文档提及)

结论

  1. 在pcap_loop的回调函数callback中,尽可能做最少的处理。可将callback放入单独线程/进程。
  2. 使用以下三个函数进行调优 pcap_setuserbufferpcap_setbuffpcap_setmintocopy
    实测效果在windows PC 上可以达到2-3Gb/s 不丢包。如果是在linux上可以达到更好效果。
posted @ 2023-03-30 13:44  guoyaobit  阅读(1508)  评论(0)    收藏  举报