我有一个在 Linux (2.6.38.8) 上运行的应用程序,使用 libpcap (>1.0) 捕获通过以太网传输的数据包。我的应用程序使用了接近 100% 的 CPU,我不确定我是否尽可能高效地使用 libpcap。
我正在努力寻找 pcap 可调参数和性能之间的任何关联。
这是我的简化代码(错误检查等省略):
// init libpcap
pcap_t *p = pcap_create("eth0", my_errbuf);
pcap_set_snaplen(p, 65535);
pcap_set_promisc(p, 0);
pcap_set_timeout(p, 1000);
pcap_set_buffer_size(p, 16<<20); // 16MB
pcap_activate(p);
// filter
struct bpf_program filter;
pcap_compile(p, &filter, "ether dst 00:11:22:33:44:55", 0, 0);
pcap_setfilter(p, &filter);
// do work
while (1) {
int ret = pcap_dispatch(p, -1, my_callback, (unsigned char *) my_args);
if (ret <= 0) {
if (ret == -1) {
printf("pcap_dispatch error: %s\n", pcap_geterr(p));
} else if (ret == -2) {
printf("pcap_dispatch broken loop\n");
} else if (ret == 0) {
printf("pcap_dispatch zero packets read\n");
} else {
printf("pcap_dispatch returned unexpectedly");
}
} else if (ret > 1) {
printf("processed %d packets\n", ret);
}
}
使用 1000 毫秒超时和 2M、4M 和 16M 缓冲区大小时的结果在高数据速率(~200 1kB 数据包/秒)下是相同的:pcap_dispatch 始终返回 2。根据 pcap_dispatch 手册页,我希望pcap_dispatch 在缓冲区已满或超时到期时返回。但是返回值为 2 时,这两个条件都不应该满足,因为只读取了 2kB 的数据,并且只经过了 2/200 秒。
如果我降低数据速率(约 100 个 1kB 数据包/秒),pcap_dispatch 会返回 2 到 7,因此将数据速率减半会影响每个 pcap_dispatch 处理的数据包数量。(我认为数据包越多越好,因为这意味着操作系统和用户空间之间的上下文切换更少——这是真的吗?)
超时值似乎也没有什么区别。
在所有情况下,我的 CPU 使用率都接近 100%。
我开始怀疑我是否应该尝试使用 PF_RING 版本的 libpcap,但从我在 SO 和 libpcap 邮件列表中阅读的内容来看,libpcap > 1.0 无论如何都会执行零拷贝,所以可能没有意义。
任何想法,指针非常感谢!G