我试图用tshark连续捕获大约20mbit / sec的stream量。 如果我在CentOS 6.5上用tshark捕获数据包,我会得到大约4%到66%的数据包丢失。 如果我在CentOS 7上做同样的事情,它从不报告任何丢失的数据包。 我实际上已经试图通过做疯狂的东西,比如向xml输出大量stream量来让它丢包。 据我可以告诉它不丢包。 我的问题是,CentOS 7有一些function,使丢包不可能? 还是它丢包,不告诉我?
作为一个例子,我执行这样的命令:
tshark -i ens224 -c 100000 -w /tmp/delme.pcap tshark -i ens224 -c 100000 -T pdml > /tmp/delme.pcap
对于第一个命令CentOS 6报告4%丢包,CentOS 7没有报告。 对于第二个命令CentOS报告66%丢包,但CentOS 7没有报告。
请注意,两台机器都运行从源代码编译的tshark 1.12.7。
我的问题是,CentOS 7有一些function,使丢包不可能?
不,但它有两个function,使得丢包的可能性要小得多:
PF_PACKET套接字的TPACKET_V3的内核版本; PF_PACKET套接字使用 TPACKET_V3的libpcap版本。 PF_PACKET使用PF_PACKET套接字在Linux 2.2及更高版本上捕获(Linux 1.x和2.0没有PF_PACKET套接字)。 原始的PF_PACKET套接字使用常规的套接字机制来传递数据包,这意味着libpcap(或任何其他捕获stream量的程序)必须在每个数据包上对该套接字执行一次recvmsg()调用。 这比在BSD和OS X上的BPF机制的工作方式要昂贵得多,因为在每次读取时都会传送多个数据包,所以在高stream量的情况下,系统调用的次数会减less。
我认为Linux 2.4引入了“turbopacket”机制(这就是“TPACKET”所代表的“T”) – “turbo”),它提供了内核和用户空间共享的内存映射缓冲区。 因此,在传递数据包时需要更less的副本,并且userland中的数据包读取循环可以在每次唤醒时处理多个数据包(等待数据包到达,userland进行select() , poll()或epoll()调用) 。 不幸的是,这种机制提供了一个固定大小的缓冲区环,libpcap必须select一个足够大的数据包来处理最大的数据包。 早期的版本select与所提供的快照长度相同大小的数据包,也就是说,对于您正在使用的Wireshark版本,可能是64K-1,这是非常浪费的 – 缓冲区最终没有足够的数据包插槽来避免超限。 一些以后的版本试图使用MTU来确定插槽的大小,但是它不能总是这样做,即使它可能是浪费的。
在一些3.x版本(3.6版本)中, TPACKET_V3了一个截然不同的turbopacket机制。 它更像BPF,一个缓冲区不包含一个数据包,它可以包含多个数据包。 这样可以更好地利用内存进行捕获,并减less了很多数据包。