深度剖析WinPcap之(九)——数据包的发送过程(8)
生活随笔
收集整理的这篇文章主要介绍了
深度剖析WinPcap之(九)——数据包的发送过程(8)
小编觉得挺不错的,现在分享给大家,帮大家做个参考.
1.7.3 发送队列方式的接口实现
1.7.3.1 PacketSendPackets函数
函数发送数据包队列到网络,函数原型如下: INT PacketSendPackets(LPADAPTER AdapterObject, PVOID PacketBuff, ULONG Size, BOOLEAN Sync) 参数AdapterObject指向一个_ADAPTER结构体,该结构体表示将发送数据包的网络适配器。 参数PacketBuff指向待发送数据包的缓冲区。 参数Size为参数PacketBuff所指缓冲区的大小。 参数Sync如果为TRUE,则根据时间戳发送数据包。如果为FALSE,则不根据时间戳,而是尽所能的快速发送各数据包。 函数返回值为实际所发送的字节数,如果该值小于Size参数规定的大小,那么发送过程中出现了错误。错误可能由驱动程序/适配器的问题或冲突的/假的数据包缓冲区导致。 该函数用来发送一个原始数据包缓冲区的内容到网络。该缓冲区能够包含任意数目的原始数据包,每个数据包都有一个dump_bpf_hdr结构体作为数据包的前缀。WinPcap或libpcap在文件中存储数据包使用一样的dump_bpf_hdr结构体,因此可以很直接的发送一个捕获的数据包文件。'Raw packets'意味着发送应用程序将不得不包含协议头,既然每个数据包’照原来的样子’被发送到网络。但是数据包的CRC并不需要计算,明显地,它将被网络接口添加。 注意:使用该函数 比直接使用一连串PacketSendPacket函数更有效率,因为数据包被缓冲到内核驱动,因此上下文的切换明显降低了。 注意:当Sync设置为TRUE,那么内核中的数据包将与一个高精度时间戳同步发送。这个操作需要消耗大量的CPU资源,但数据包的发送通常很精确(可达数微秒左右),这依赖于机器的性能计数器(performance counter)的精度。如此精度是采用pcap_sendpacket函数不可能达到的。 INT PacketSendPackets(LPADAPTER AdapterObject, PVOID PacketBuff, ULONG Size, BOOLEAN Sync) { BOOLEAN Res; DWORD BytesTransfered, TotBytesTransfered=0; struct timeval BufStartTime; LARGE_INTEGER StartTicks, CurTicks, TargetTicks, TimeFreq;if (AdapterObject->Flags == INFO_FLAG_NDIS_ADAPTER) { /*获得发送队列的起始时间戳*/ BufStartTime.tv_sec = ((struct timeval*)(PacketBuff))->tv_sec; BufStartTime.tv_usec = ((struct timeval*)(PacketBuff))->tv_usec;
/*获的参考的时间计数器*/ QueryPerformanceCounter(&StartTicks); QueryPerformanceFrequency(&TimeFreq); CurTicks.QuadPart = StartTicks.QuadPart;
do{ //把数据发送给驱动程序 Res = (BOOLEAN)DeviceIoControl( AdapterObject->hFile, (Sync)?BIOCSENDPACKETSSYNC:BIOCSENDPACKETSNOSYNC, (PCHAR)PacketBuff + TotBytesTransfered, Size - TotBytesTransfered, NULL, 0, &BytesTransfered, NULL);
TotBytesTransfered += BytesTransfered;
//从循环中退出,发送结束或出错 if(TotBytesTransfered >= Size || Res != TRUE) break;
//计算发送下一块数据的时间间隔 TargetTicks.QuadPart = StartTicks.QuadPart + (LONGLONG)((((struct timeval*) ((PCHAR)PacketBuff + TotBytesTransfered))->tv_sec – BufStartTime.tv_sec) * 1000000 + (((struct timeval*) ((PCHAR)PacketBuff + TotBytesTransfered))->tv_usec - BufStartTime.tv_usec)) *(TimeFreq.QuadPart ) / 1000000; //等待时间间隔的逝去 while( CurTicks.QuadPart <= TargetTicks.QuadPart ) QueryPerformanceCounter(&CurTicks);
} while(TRUE); } else {//错误,未知设备类型 TotBytesTransfered = 0; }
return TotBytesTransfered; }
本文出自 “千江月” 博客,请务必保留此出处http://eslxf.blog.51cto.com/918801/214880
转载于:https://blog.51cto.com/runhook/387939
总结
以上是生活随笔为你收集整理的深度剖析WinPcap之(九)——数据包的发送过程(8)的全部内容,希望文章能够帮你解决所遇到的问题。
- 上一篇: 5种iterator
- 下一篇: CCNA学习与实验指南(640-802)