winsend8

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结构体作为数据包的前缀。WinPcaplibpcap在文件中存储数据包使用一样的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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值