深度剖析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)