不用callback捕获数据报
这节的例子很像先前的一章(获得网卡的高级信息),但是这一节中使用的是pcap_next_ex()而非pcap_loop()。
pcap_loop()函数的基于回调包捕获机制是一流的,在某些情况下是不错的选择。但是在一些情况下处理回调并不特别好:这会使程序变的复杂并且在象多线程或C++类这些情况下它看起来到象一块绊脚石。
在这些情况下,pcap_next_ex()允许直接调用来接收包。使用pcap_next_ex()可以仅仅在程序员需要接受的时候接受包。
它的参数和回调捕捉(pcap_loop())相同:有一个网卡描述符和一对指针,这两个指针会被初始化并返回给用户。一个指向一个pcap_pkthdr结构,另一个是指向接收数据的缓冲区。
下面的程序我们将循环调用前一节的例子中的回掉部分,只是把它移到了main里面了,位于函数pcap_next_ex()之后。
pcap_next_ex()只在Win32环境下才行因为它不是原始libpcap API中的一部分,这就意味着依赖于这个函数的代码不会在UNIX下工作。那么为什么我们用pcap_next_ex()而不用pcap_next()?因为pcap_next()有许多限制,在很多情况下并不鼓励用它。首先它的效率很低,因为它隐藏了回掉方法却任然依赖于pcap_dispatch()这个函数。其次它不能够识别文件结束标志EOF,所以对来自文件的数据流它几乎无能为力。
最后值得注意的是pcap_next_ex()在成功,超时,出错和文件结束的情况下会返回不同的值。
附原文:
The example program in this lesson behaves exactly like the previous program (Opening an adapter and capturing the packets), but it uses pcap_next_ex() instead of pcap_loop().
The callback-based capture mechanism of pcap_loop() is elegant and it could be a good choice in some situations. However, handling a callback is sometimes not practical -- it often makes the program more complex especially in situations with multithreaded applications or C++ classes.
In these cases, pcap_next_ex() retrievs a packet with a direct call -- using pcap_next_ex() packets are received only when the programmer wants them.
The parameters of this function are the same as a capture callback -- it takes an adapter descriptor and a couple of pointers that will be initialized and returned to the user (one to a pcap_pkthdr structure and another to a buffer with the packet data).
In the following program, we recycle the callback code of the previous lesson's example and move it inside main() right after the call to pcap_next_ex().
/* codes */
Why do we use pcap_next_ex() instead of the old pcap_next()? Because pcap_next() has some drawbacks. First of all, it is inefficient because it hides the callback method but still relies on pcap_dispatch(). Second, it is not able to detect EOF, so it's not very useful when gathering packets from a file.
Notice also that pcap_next_ex() returns different values for success, timeout elapsed, error and EOF conditions.
#end