如何在libpcap数据包接收函数中定期超时
我在 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 机器上):
“... ... to_ms 指定读取超时(以毫秒为单位)。读取超时用于安排读取不一定在看到数据包时立即返回,而是等待一段时间以允许更多数据包到达并在一次操作中从操作系统内核读取多个数据包,并非所有平台都支持读取超时,在不支持的平台上,读取超时将被忽略......
注意:读取实时捕获时,pcap_dispatch() 不一定会在读取超时时返回;在某些平台上,不支持读取超时,并且在其他平台上,直到至少一个数据包到达后计时器才会启动。这意味着读取超时不应用于交互式应用程序等,以允许数据包捕获循环定期“轮询”用户输入,因为无法保证 pcap_dispatch() 在超时到期后返回。 ...”
因此,我想我需要自己实现 GENERIC (与平台无关)超时机制,如下所示?
- 使用 pcap_open_live() 创建一个 pcap_t 结构。
- 将其设置为非阻塞模式pcap_setnonblock(pcap_t...).
- 使用已注册的操作系统计时器轮询此非阻塞 pcap_t,例如:
注册操作系统计时器_x,并重置计时器_x;
while(1) {
if(timer_x 超时) {做一些需要定期做的事情;重置timer_x;}
通过调用pcap_dispatch(pcap_t...)/pcap_next_ex(pcap_t...)轮询pcap_t以接收一些数据包;
对这些数据包做一些事情;
}// while(1)
问候,
直流
I found this post in stackoverflow.com
listening using Pcap with timeout
I am facing a similar (but different) problem: what is the GENERIC (platform-independent) method to timeout periodically when receiving captured packets by using libpcap packet receiving functions?
Actually, I am wondering if it is possible to periodically timeout from the pcap_dispatch(pcap_t...) / pcap_next_ex(pcap_t...)? If that is possible, I can use them just like using the classic select(...timeout) function ( http://linux.die.net/man/2/select ).
In addition, from the official webpage ( http://www.tcpdump.org/pcap3_man.html ), I found the original timeout mechanism is considered buggy and platform-specific (This is bad, since my program may run on different Linux and Unix boxes):
"... ... to_ms specifies the read timeout in milliseconds. The read timeout is used to arrange that the read not necessarily return immediately when a packet is seen, but that it wait for some amount of time to allow more packets to arrive and to read multiple packets from the OS kernel in one operation. Not all platforms support a read timeout; on platforms that don't, the read timeout is ignored ... ...
NOTE: when reading a live capture, pcap_dispatch() will not necessarily return when the read times out; on some platforms, the read timeout isn't supported, and, on other platforms, the timer doesn't start until at least one packet arrives. This means that the read timeout should NOT be used in, for example, an interactive application, to allow the packet capture loop to "poll" for user input periodically, as there's no guarantee that pcap_dispatch() will return after the timeout expires... ..."
Therefore, I guess I need to implement the GENERIC (platform-independent) timeout mechanism by myself like below?
- create a pcap_t structure with pcap_open_live().
- set it in nonblocking mode with pcap_setnonblock(pcap_t...).
- poll this nonblocking pcap_t with registered OS timer like:
register OS timer_x, and reset timer_x;
while(1) {
if(timer_x times out)
{do something that need to be done periodically; reset timer_x;}
poll pcap_t by calling pcap_dispatch(pcap_t...)/pcap_next_ex(pcap_t...) to receive some packets;
do something with these packets;
}//end of while(1)
Regards,
DC
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您可以使用 pcap_fileno() 和 select() 获取句柄。
OfferReceiver::Listen 中有一个此处的示例()。
You can get the handle with pcap_fileno() and select() it.
There's a sample here in OfferReceiver::Listen().