使用WinPcap接收网络适配器上收集到的网络上的数据报文,首先需要创建一个高优先级别的任务或者线程,一般在TCP/IP协 议栈的网络接口层初始化时即需要创建一个这样的任务或者线程,然后在该任务或者线程函数里调用PacketAllocatePacket()为接收数据报 文创建网络数据报结构,再调用PacketInitPacket()函数为接收的数据报文分配内存缓冲区,这个缓冲区需要尽量大一点儿,否则一旦网络上数 据报文比较多,而协议栈上层来不及处理,则会造成数据报文的丢失.接下来便是循环的调用PacketReceivePacket()函数从指定的网络适配 器读取数据报文,并将数据报文拷贝到协议栈的内存空间,再通过操作系统提供的任务或线程间通信的机制将该数据报文发送到TCP/IP协议栈的接收任务或者线程进行报文的分析和处理.这个数据接收的任务和线程将永远不会返回,始终循环调用PacketReceivePacket()函数读取网络适配器上接收到的网络上传输过来的数据报文并将其交付给TCP/IP协议栈进行处理.

6 在Windows平台上配置双协议栈的问题

由于Windows平台本身自带有TCP/IP协议栈,而我们又需要在Windows平台上运行一个嵌入式TCP/IP协议栈,实际上是在Windows这一个操作系统上配置了双TCP/IP协议栈.

要使这两个TCP/IP协议栈相互之间互不影响并能各自良好的运行,首先需要为两个协议栈各自分配不同的IP地址;其次在嵌入式TCP/IP协议栈中的数据链路层的Mac地址,一定不能使用Windows平台的TCP/IP协议栈使用的网络适配器的地址,除非计算机装有两块网络适配器,Windows平台的TCP/IP协议栈使用一个网络适配器进行数据的收发,而嵌入式TCP/IP协议栈使用另一个网网络适配器收发数据报文.其实在嵌入式TCP/IP协 议栈中,其链路层的Mac地址可以通过修改程序代码设置任意的虚拟Mac地址,但这必须首先调用WinPcap的PacketSetHwFilter() 函数设置网络适配器的接收模式为NDIS_PACKET_TYPE_PROMISCUOUS混杂模式)用于指定网罗适配器接收所有流过的数据报文,否 则,网络适配器会根据本身的Mac地址对网络上接收到的数据报文进行Mac过滤,丢弃掉不属于该网络适配器接收的数据报文.

7 小结

作者在工作中按照上述方法,成功的在Windows平台上运行并调试了Linux的TCP/IP协议栈,并最终将其移植到VxWorks操作系统中运行.在调试过程中,作者明显感觉Windows的VC6开发平台下调试确实比直接使用Tornado调试要方便和快捷许多.由于前期在Windows平台上调试时解决了大部分移植和修改TCP/IP协议栈的问题,后期在Tornado下调试时基本上没有花费太多的时间,大大提高了工作的效率,减小了开发的周期.


相关内容