如何检查libpcap中的数据包可用性

时间:2013-05-14 00:49:28

标签: c multithreading mutex libpcap

我使用libpcap来捕获数据包,一旦数据包可用,我需要将数据包放入FIFO队列。但FIFO队列由2个线程共享,一个线程调用pcap_next()并将数据包放入FIFO队列。另一个线程从fifo队列中获取数据包。所以我必须把它与互斥量联系起来。如下所示:

u_char* pkt;
for(;;){
    pkt = pcap_next();
    lock(&mutex);
    some_process(pkt);
    insert(pkt, list);
    unlock(&mutext);
 }

pcap_next()与数据包缓冲区相关,如果缓冲区中没有数据包,则pcap_next()被阻止。如果存在/是数据包,则每次调用pcap_next()都会返回1个数据包。

它只能为每个锁定 - 解锁操作对获取一个数据包,如果数据包到达不频繁,则可以。但是如果数据包到达频繁,就像在缓冲区中存在许多未决数据包一样,为一个数据包提供锁定解锁操作对会消耗一些资源。

我希望:在处理和插入数据包之后,我立即可以检查数据包缓冲区中是否有可用的数据包。如果有,继续处理和插入。否则,解锁互斥锁并返回循环。

有解决方法吗?

2 个答案:

答案 0 :(得分:1)

尝试诸如

之类的内容
/*
 * XXX - this can fail on some platforms and with some devices,
 * and there may be issues with select() on this.  See the
 * pcap_get_selectable_fd() man page for details.
 */
pcap_fd = pcap_get_selectable_fd(p);
pcap_setnonblock(p);  /* XXX - check for failure */

for (;;) {
    fd_set fdset;
    struct timeval timeout;

    /*
     * Wait for a batch of packets to be available.
     */
    FD_ZERO(&fdset);
    FD_SET(pcap_fd, &fdset);
    timeout.tv_sec = 1;
    timeout.tv_usec = 0;
    if (select(1, &fdset, NULL, NULL, &timeout) == -1) {
        report an error;
    } else {
        lock(&mutex);
        pcap_dispatch(p, -1, callback, pointer-to-stuff);
        unlock(&mutex);
    }
}

这样,您可以锁定互斥锁,处理整批数据包,然后解锁互斥锁。许多操作系统捕获机制批量传送多个数据包,因此在这种情况下每批将有一个锁定/解锁配对。

回调会执行some_process(pkt);insert(pkt, list);内容。

一旦完成批处理,下一批可能会立即可用,因此无法实现绝对最小的锁定/解锁对;但是,绝对最小值可能会在很长一段时间内锁定另一个线程,因此它永远不会取得任何进展,因此锁定和解锁每个批处理可能是最好的。

答案 1 :(得分:0)

只使用pcap_dispatch(),或选择()使用非阻塞样式pcap_next()