一同分享编程是种快乐  

    距离上次发博文有两三个星期的时候了,期间看了一些书,如《Effective C++》、《Windows核心编程》。感觉对计算机有了一个新的认识,自己以前对程序的见解是那么肤浅,完全没有操作系统的概念,也没有程序各部分与内存关系的认识。下面开始介绍这个类。

1. 类成员介绍 

Code

    这个类包括了用于初始化网络的InitPcap,用于返回网络设备信息的DevMsg,用于选择设备的SetDev,用于发送数据包的SendPacket和用于接收数据包的GetPacket。用户必须先调用InitPcap,再调用SetDev,然后才能执行发送或接收。由于接收函数必采用回调方式才能工作,所以这里typedef了一个回调函数的指针void packet_handler(u_char *, const struct pcap_pkthdr *, const u_char *),它的三个参数都是pcap.h里头的回调函数的参数。实际上,从WinPcap到用户的使用共有两次回调的过程,一是WinPcap提供的回调,另一个是封装类的时候提供的回调。
2. 类的实现

Code

    SendPacket中使用了关键段保证线程安全,这样子在使用多线程的时候就不会因为网络设备被同时调用而出错。SendPacket的参数包括了一个UCHAR指针及待发送数据的长度,用户使用时把待发送的数组的地址传入参数一,把数组长度传入参数二。GetPacket的参数包括一个函数指针及接收数据包的数目,这里的函数指针就是用户需要被回调的函数的地址。用户使用的时候把函数名(即函数指针)传入参数一,把接收的数据包的个数传入参数二,当有数据包被检测到的时候回调函数就会被执行,当接收的数据包的数目超出cnt时,pcap_loop就会退出(在此之前pcap_loop是没有退出的,它是一个循环并阻塞等待数据包的函数)。
    由于本人是从C#转过来的(虽然开始学的是C++,后来由于种种原因开始使用起C#),对于event方式的回调比较熟悉。开始要写C++的回调一直没弄明白,查了一些中文的资料觉得都看得糊里糊涂的,后来看到外国的资料才明白了http://www.newty.de/fpt/callback.html。其实回调的关键就是把需要被回调的函数的地址作为参数传入另一个函数,还有你必须给这个函数定义一个格式,如参数和返回值,这样子回调的时候程序才能根据地址及参数列表从内存中调用被回调的函数。当然,定义函数格式的话可以通过typedef的形式在头文件中定义,也可以在参数列表中直接定义,如void (*p) (...)这样。
3.写在后面
    发送函数只调用了比较简单的pcap_sendpacket,而接收也是调用了pcap_loop。可能你也发现了发送还有pcap_sendqueue_queue,接收还有pcap_next_ex,不过对于简单的任务使用前者就足够了。

posted on 2009-08-27 20:20  sober  阅读(2954)  评论(7编辑  收藏  举报