我正在为非常高流量的网络编写监控程序(高清视频通过网络流式传输)。大多数数据包都非常大,我只想看标题(仅限IP和UDP / TCP)。当然,我想避免复制整个数据的开销。 libpcap是否必须给我一份整个数据包的副本?如果是,是否有符合我需求的图书馆?
答案 0 :(得分:6)
这里似乎有两个问题:
对于第一个问题:
任何使用libpcap在各种操作系统中运行的机制的代码可能至少完成了一个副本 - 从mbufs / skbuff / STREAMS缓冲区复制到机制的缓冲区。对于Linux,当tpacket机制不正在使用时,skbuff 可能只是在接收队列上排队,用于PF_PACKET
套接字libpcap正在使用。
可能有另一个副本 - 从该缓冲区到用户区的副本;如果libpcap使用“零拷贝”机制,例如Linux tpacket机制(libpcap 1.0及以后默认使用),则不会发生第二个拷贝。如果没有使用零拷贝机制,将发生。
但是,如果您在Linux系统上使用pcap_next()
或pcap_next_ex()
并且正在使用tpacket机制,则需要一个单独的副本,从内存映射缓冲区到私有缓冲区;如果您使用pcap_dispatch()
或pcap_loop()
,则不会发生这种情况。
关于第二个问题:
这就是pcap_open_live()
和pcap_set_snaplen()
的“snaplen”参数的含义 - 它允许您指定应该捕获不超过“snaplen”字节的数据包数据,这意味着不再需要而不是复制许多字节。
请注意,此长度包含链接层标头,并且这些标头可包含“元数据”标头,例如您可能在802.11适配器上获得的radiotap标头。此标头可能是可变长度的(例如,在802.11上,802.11标头是可变长度的,如果您获得radiotap标头,那么它们也是可变长度的。)
此外,IPv4和TCP标头都可以有选项,IPv6数据包可以有扩展标头,因此IP和TCP标头的长度也可以变化。
这意味着您可能必须确定要使用的“最坏情况”快照长度;没有办法明确地说“不要给我任何超过TCP / UDP标头的东西”,你只能说“给我不超过N个字节”。