捕获网络流量以进行调试时,似乎有两种常见方法:
>使用原始套接字.
>使用libpcap.
在性能方面,这两种方法之间有很大差异吗? libpcap似乎是一种很好的兼容方式来收听真实的网络连接或重放一些固定数据,但是这个功能集是否会带来性能损失?
libpcap使用PF_PACKET来捕获接口上的数据包.请参阅以下链接.
https://www.kernel.org/doc/Documentation/networking/packet_mmap.txt
从上面的链接
在Linux 2.4 / 2.6 / 3.x中,如果未启用PACKET_MMAP,则捕获过程非常紧凑
效率低下.它使用非常有限的缓冲区,需要一个系统调用
捕获每个数据包,如果要获取数据包的时间戳,则需要两个数据包
(像libpcap一样).
另一方面,PACKET_MMAP非常有效. PACKET_MMAP提供了一个大小
在用户空间中映射的可配置循环缓冲区,可用于任何一个
发送或接收数据包.这样读取数据包只需要等待它们,
大多数情况下,不需要发出单个系统调用.关于
传输时,可以通过一个系统调用发送多个数据包来获取
最高带宽.通过在内核和用户之间使用共享缓冲区
还具有最小化数据包副本的好处.
性能改进可能因使用PF_PACKET实现而异.
从https://www.kernel.org/doc/Documentation/networking/packet_mmap.txt –
据说TPACKET_V3带来以下好处:
*)〜15 – cpu使用率减少20%
*)数据包捕获率增加约20%
使用libpcap的缺点 –
>如果应用程序需要保存数据包,则可能需要进行此操作
传入数据包的副本.
请参阅pcap_next_ex的联机帮助页.
pcap_next_ex()读取下一个数据包并返回成功/失败指示.如果数据包读取没有问题,指针
由pkt_header参数指向设置为指向
pcap_pkthdr用于数据包的结构,以及指向的指针
pkt_data参数设置为指向数据包中的数据.该
struct pcap_pkthdr和分组数据不会被释放
呼叫者,并且在下次呼叫后不保证有效
pcap_next_ex(),pcap_next(),pcap_loop()或pcap_dispatch();如果
代码需要它们保持有效,它必须复制它们.
>如果应用程序只对传入感兴趣,则性能下降
数据包.
PF_PACKET用作内核中的抽头,即所有传入和传出的数据包都被传送到PF_SOCKET.这导致对所有传出数据包进行昂贵的packet_rcv调用.由于libpcap使用PF_PACKET,因此libpcap可以捕获所有传入和传出的数据包.
如果应用程序只对传入的数据包感兴趣,那么可以通过在libpcap句柄上设置pcap_setdirection来丢弃传出的数据包. libpcap通过检查数据包元数据上的标志在内部丢弃传出的数据包.
所以本质上,libpcap仍然可以看到传出的数据包,但以后才会被丢弃.对于仅对传入数据包感兴趣的应用程序,这是性能损失.