libpcap/npcap,libpcap 千兆网满速 调优

发布时间 2023-03-30 13:39:27作者: guoyaobit

工作中需要用PC采集FPGA发送的数据包,发送间隔很快,100us以内,如何能够把数据收进来,不丢包成为了问题的关键。libpcap是比较成熟的库,能够实现该功能
网卡抓取数据流向
选项1: 网卡-> 驱动/内核-> 用户态->程序通过libpcap api读入-> 放入内存后续处理
选项2: 网卡->驱动/内核-> 硬盘(pcap格式)

通常使用选项1,因为用户需要的不是原始数据而是处理结果

问题:如果如何解决丢包问题,需要对每个环节进行优化
1. 网卡,网卡的性能可以进行优化,在linux中可以通过ethtool 配置查看手册
2. 驱动/内核 ,pcap_setbuff(),在win环境下,驱动和内核是独立的,而在linux下,驱动需要加载在内核中。网卡的数据copy 进入ring buffer,ring buffer 是一块内存区域,在windows 中对应的是 NoPagePool,size可以通过 pcap_setbuff 设置,size 默认值为 1e6.需要注意的是ring buffer 满了后,数据包会被丢弃。丢包数量,可以通过libpcap api查看。
3. 从驱动/内核 -> 用户态 ,从kernel buffer 到user buffer 的copy . 触发过程是由pcap_setmintocopy 决定,默认值为16e3,也就是超过size 后,进行一次copy.
也就是减小size ,copy更加频繁,那么延迟更低,最小可设置为1。增加size,copy 频率降低,cpu实时性要求降低,丢包率下降。
4. 关键参数 : user buffer ,默认为256e3,可进行增加,降低丢包。pcap_setuserbuffer()
5. Libpcap api 在windows 推荐使用npcap ,抓包api推荐 pcap_loop ,而不是pcap_next_ex 因为会多一次copy (官方文档提及)
6. 数据读入 (most important ) 快速将网络包从内存中读出是问题的关键,不要再pcap_loop中进行耗时的copy 、计算等。