[英]how to check packet availability in 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個數據包。
它只能為每個鎖定/解鎖操作對獲取一個數據包,如果數據包到達不頻繁,則可以。 但是,如果數據包到達頻繁,例如在緩沖區中有許多待處理的數據包,那么為一個數據包設置一個鎖定-解鎖操作對會浪費一些資源。
我希望是:在處理並插入數據包之后,我可以立即檢查數據包緩沖區中是否有可用的數據包。 如果有,請繼續處理和插入。 否則,請解鎖互斥鎖並返回循環。
有沒有解決方法?
嘗試諸如
/*
* 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);
}
}
這樣,您可以鎖定互斥鎖,處理整批數據包,然后解鎖互斥鎖。 許多OS捕獲機制會批量分發多個數據包,因此在這種情況下,每批將有一對鎖定/解鎖對。
回調將執行some_process(pkt);
並insert(pkt, list);
東西。
這是可能的,一旦你有一個批次完成后,下一批將立即提供,所以這並不能達到鎖的絕對最小/解鎖對; 但是,絕對最小值可能會在相當長的一段時間內將另一個線程鎖定,從而使其永遠無法取得任何進展,因此在每個批次周圍鎖定和解鎖可能是最好的。
只需使用pcap_dispatch()或具有非阻塞樣式pcap_next()的select()
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.