我如何使libpcap/pcap_loop非阻塞

How do I make libpcap/pcap_loop non-blocking?

本文关键字:loop pcap 何使 libpcap      更新时间:2023-10-16

我目前使用libpcap在混杂模式下嗅探流量

int main() 
{
    // some stuff
    printf("Opening device: %sn", devname.c_str());
    handle = pcap_open_live(devname.c_str(), 65536 , 1 , 0 , errbuf);
    if (handle == NULL)
    {
        fprintf(stderr, "Couldn't open device %s : %s..." , devname.c_str(), errbuf);
        return 1;
    }
    printf(" Donen");
    pcap_loop(handle , -1 , process_packet , NULL);
    // here run a thread to do some stuff. however, pcap_loop is blocking
    return 0;
}

我想添加一个外部线程做一些其他的东西。我如何改变上面的代码,使其非阻塞?

当你在libpcap上使用非阻塞模式时,你必须使用pcap_dispatch,但请注意,pcap_dispatch可以在阻塞或非阻塞模式下工作,这取决于你如何设置libpcap,要设置libpcap在非阻塞模式下工作,你必须使用pcap_setnonblock:

int pcap_setnonblock(pcap_t *p, int nonblock, char *errbuf);

阻塞和非阻塞之间的区别不是永远运行的循环,而是阻塞函数pcap_dispatch等待数据包并仅在收到该数据包时返回,然而,在非阻塞模式下,函数立即返回并且回调必须处理数据包。

在"非阻塞"模式下,尝试从捕获中读取如果当前没有数据包,则使用pcap_dispatch()的描述符将可读,立即返回0,而不是阻塞等待数据包到达。Pcap_loop()和pcap_next()则不会在"非阻塞"模式下工作

http://www.tcpdump.org/manpages/pcap_setnonblock.3pcap.html

pcap_loop将一直持续到所有输入结束。如果不想要这种行为,可以在循环中调用pcap_dispatch。根据定义,pcap_loop永远不会返回,它意味着总是搜索更多的数据。

我使用pcap_next_ex。它返回一个结果,指示是否读取数据包。这样我就可以管理我自己的线程。请看下面的例子。pcap_open中的read_timeout也会影响此功能