我目前的工作如下:
struct pcap_pkthdr *phdr;
const u_char *data;
pcap_next_ex(descriptor, &phdr, &data);
memcpy((void*)mybuf, phdr, sizeof(*phdr));
memcpy((void*)mybuf + sizeof(*phdr), data, phdr->len);
但我想做的是以下内容,即提供预分配的缓冲区。
u_char mybuf[2048];
pcap_next_ex(descriptor, mybuf, mybuf + 16); // 16 is size of pkthdr
第二个例子因为指针类型错误而无法编译,但我认为我的问题可以通过这种方式更好理解。我正在从10G界面阅读,速度非常重要。我想对代码的某些部分进行基准测试,例如,使用自己的预分配数据包缓冲区而不是libpcap中的隐藏分配/缓冲区。
是否有方法或API使libpcap采用预先分配的缓冲区来将pcap_next_ex的结果写入?
答案 0 :(得分:3)
从浏览libpcap source code开始,似乎没有办法传递预先分配的缓冲区。但是,它很可能已经使用了内部预分配的缓冲区。例如,对于Linux上的实时捕获,pcap_next_ex()
会在pcap-linux.c
中深入调用pcap_read_packet()
。在这里,您可以看到返回的指针只是属于捕获句柄的较大读取缓冲区的偏移量。我还没有看过其他操作系统的实现,但我怀疑它们是相似的。
允许您传入自己的缓冲区要么平台实现要将数据从它们自己的内部缓冲区复制到缓冲区(效率非常低),要么严重限制它们管理自己的系统调用缓冲的能力(内存)映射,每次系统调用接收多个数据包等)。无论哪种方式,很可能这不是潜在优化的来源。
另请参阅this mailing list thread,其中讨论了pcap_next_ex()
和旧pcap_loop()
界面的相对效果。
interjay指出Linux实时捕获实现无论如何都要复制,因为要求缓冲内容在调用后保持有效(参见pcap-linux.c
的第4452行)。代码中的注释表明pcap_loop()
可能确实更快,因为缓冲区仅暴露给回调函数,因此在回调返回后其内容不需要保持有效。