如何使 libpcap/pcap_loop 成为非阻塞的?

How do I make libpcap/pcap_loop non-blocking?

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

int main() 
{
    // some stuff
    printf("Opening device: %s\n", 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(" Done\n");

    pcap_loop(handle , -1 , process_packet , NULL);
    // here run a thread to do some stuff. however, pcap_loop is blocking
    return 0;
}

我想添加一个外部线程来做一些其他的事情。如何更改上面的代码使其成为非阻塞的?

pcap_loop 意味着继续直到所有输入结束。如果您不想要这种行为,请改为在循环中调用 pcap_dispatch。根据定义 pcap_loop 永远不会 return,它意味着总是搜索更多数据。

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

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

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

In "non-blocking" mode, an attempt to read from the capture descriptor with pcap_dispatch() will, if no packets are currently available to be read, return 0 immediately rather than blocking waiting for packets to arrive. pcap_loop() and pcap_next() will not work in "non-blocking" mode.

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

我使用pcap_next_ex它returns一个结果表明是否读取了数据包。这样我就可以管理我自己的线程的获取。请参阅示例 herepcap_open中的read_timeout也会影响这个功能。