2

我在 stackoverflow.com 中发现这篇文章 使用 Pcap 监听超时

我面临一个类似(但不同)的问题:使用 libpcap 数据包接收功能接收捕获的数据包时,什么是 GENERIC(与平台无关)方法定期超时?实际上,我想知道是否可以从 pcap_dispatch(pcap_t...) / pcap_next_ex(pcap_t...) 定期超时?如果可能的话,我可以像使用经典的 select(...timeout) 函数(http://linux.die.net/man/2/select)一样使用它们。

另外,从官方网页(http://www.tcpdump.org/pcap3_man.html),我发现原来的超时机制被认为是错误的和特定于平台的(这很糟糕,因为我的程序可能在不同的 Linux 和Unix box):
"... ... to_ms 以毫秒为单位指定读取超时。读取超时用于安排读取不一定在看到数据包时立即返回,而是等待一段时间以允许更多数据包到达并在一次操作中从操作系统内核读取多个数据包。并非所有平台都支持读取超时;在不支持的平台上,读取超时被忽略......
注意:读取实时捕获时,读取超时时 pcap_dispatch() 不一定会返回;在某些平台上,不支持读取超时,而在其他平台上,计时器在至少一个数据包到达之前不会启动。这意味着不应在例如交互式应用程序中使用读取超时,以允许数据包捕获循环定期“轮询”用户输入,因为无法保证 pcap_dispatch() 将在超时到期后返回。 ……”

因此,我想我需要自己实现 GENERIC(平台无关)超时机制,如下所示?

  1. 使用 pcap_open_live() 创建一个 pcap_t 结构。
  2. 使用 pcap_setnonblock(pcap_t...) 将其设置为非阻塞模式。
  3. 使用已注册的 OS 计时器轮询此非阻塞 pcap_t,例如:

注册 OS timer_x,并重置 timer_x;

而(1){

if(timer_x timeout) {做一些需要定期做的事情;重置 timer_x;}

通过调用 pcap_dispatch(pcap_t...)/pcap_next_ex(pcap_t...) 来轮询 pcap_t 以​​接收一些数据包;
对这些数据包做点什么;

}//while(1) 结束

问候,
直流

4

1 回答 1

2

您可以使用 pcap_fileno() 和 select() 获取句柄。在OfferReceiver ::Listen() 中有一个示例。

于 2011-07-27T08:03:10.530 回答