// Open the ethernet adapter
handle = pcap_open_live("eth0", 65356, 1, 0, errbuf);
// Make sure it opens correctly
if(handle == NULL)
{
printf("Couldn't open device : %s\n", errbuf);
exit(1);
}
// Compile filter
if(pcap_compile(handle, &bpf, "udp", 0, PCAP_NETMASK_UNKNOWN))
{
printf("pcap_compile(): %s\n", pcap_geterr(handle));
exit(1);
}
// Set Filter
if(pcap_setfilter(handle, &bpf) < 0)
{
printf("pcap_setfilter(): %s\n", pcap_geterr(handle));
exit(1);
}
// Set signals
signal(SIGINT, bailout);
signal(SIGTERM, bailout);
signal(SIGQUIT, bailout);
// Setup callback to process the packet
pcap_loop(handle, -1, process_packet, NULL);process_packet函数去掉了头,并对数据进行了一些处理。然而,当它花费太长的时间,我认为它是丢包。
如何使用pcap侦听udp数据包,并能够在不丢失数据包的情况下对数据进行一些处理?
发布于 2013-08-29 02:17:13
那么,您没有无限的存储空间,所以,如果您持续运行速度比数据包到达的速度慢,您将在某一时刻丢失数据。
当然,如果您拥有相当大的存储空间,而且平均来说,您不会落后(例如,您可能在突发事件中跑得很慢,但是在安静的时候,您可以迎头赶上),这将缓解问题。
一些网络嗅探器会这样做,只需将原始数据写入文件以供以后分析。
这是一个技巧,你也可以使用,虽然不一定对一个文件。可以使用大量的内存结构,比如循环缓冲区,其中一个线程(捕获线程)写入原始数据,另一个线程(分析)读取和解释数据。而且,因为每个线程只处理缓冲区的一端,您甚至可以在不使用锁(或者使用非常短的锁)的情况下设计它。
这也使得您很容易检测出缓冲区是否用完并引发某种错误,而不仅仅是在应用程序级别丢失数据。
当然,这一切都取决于您的“简单和快速”捕获线程能够跟上流量。
澄清我的意思,修改您的process_packet函数,使它只将原始数据包写入一个庞大的循环缓冲区(检测溢出并相应地执行操作)。这应该使它尽可能快,避免pcap本身丢包。
然后,有一个分析线程,该线程从队列中删除内容,并执行以前在process_packet中完成的工作(“去掉标题并对数据进行一些处理”)。
另一种可能的解决方案是增大pcap内部缓冲区的大小。根据手册页:
到达捕获的数据包被存储在缓冲区中,以便应用程序不必在它们到达时立即读取它们。 在某些平台上,可以设置缓冲区的大小;太小的大小可能意味着,如果捕获的数据包太多,快照长度不限制缓冲的数据量,则如果缓冲区在应用程序读取数据包之前填满,则可以丢弃数据包,而太大的缓冲区可能会占用更多不可分页的操作系统内存,以防止数据包被丢弃。 缓冲区大小用
pcap_set_buffer_size()设置。
想到的唯一其他可能性是确保您对每个数据包所做的处理尽可能地优化。
将处理分解为收集和分析,可以缓解跟不上的问题,但仍然需要安静的时间才能赶上。如果您的网络流量始终超出您的分析所能处理的范围,那么您所做的就是延迟问题。优化分析可能是保证您永远不会丢失数据的唯一方法。
https://stackoverflow.com/questions/18501212
复制相似问题