本帖最后由 republican 于 2012-6-1 22:56 编辑
写的太烂了,不好意思开源的~~
不过有兴趣者可以试着提高以下代码的效率(以下代码执行起来是非常慢的~)
#include <ButtonConstants.au3>
#include <EditConstants.au3>
#include <GUIConstantsEx.au3>
#include <GUIListBox.au3>
#include <StaticConstants.au3>
#include <WindowsConstants.au3>
#include <Array.au3>
#include <Winpcap.au3>
Opt("GUIOnEventMode", 1)
#Region ### START Koda GUI section ### Form=
$Form1 = GUICreate("Form1", 346, 456, 192, 124)
$Label1 = GUICtrlCreateLabel("外网下传:", 16, 16, 64, 17)
$Label2 = GUICtrlCreateLabel("0 KB/s", 80, 16, 52, 17,0x002)
$Label3 = GUICtrlCreateLabel("外网上传:", 136, 16, 64, 17)
$Label4 = GUICtrlCreateLabel("0 KB/s", 200, 16, 51, 17,0x002)
;~ $Label5 = GUICtrlCreateLabel("内网下载:", 16, 40, 64, 17)
;~ $Label6 = GUICtrlCreateLabel("0 KB/S", 80, 40, 54, 17,0x002)
;~ $Label7 = GUICtrlCreateLabel("内网上传:", 136, 40, 64, 17)
;~ $Label8 = GUICtrlCreateLabel("0 KB/S", 200, 40, 54, 17,0x002)
$Button1 = GUICtrlCreateButton("Button1", 264, 16, 65, 25)
GUICtrlSetOnEvent (-1, "_Handle" )
$Edit1 = GUICtrlCreateEdit("", 8, 64, 329, 81)
$Edit2 = GUICtrlCreateEdit("", 8, 152, 329, 113)
$List1 = GUICtrlCreateList("", 8, 272, 329, 149)
$Button2 = GUICtrlCreateButton("Button2", 256, 424, 81, 25)
GUICtrlSetOnEvent (-1, "_Handle" )
$Button3 = GUICtrlCreateButton("Button3", 128, 424, 81, 25)
GUICtrlSetOnEvent (-1, "_Handle" )
GUISetState(@SW_SHOW)
#EndRegion ### END Koda GUI section ###
GUISetOnEvent($GUI_EVENT_CLOSE, "_exit")
Global $CaptureStatue = 0
$WinPcap =_PcapSetup() ;仅仅打开DLl,和ErrorBuffer
;~ MsgBox(64,0,$WinPcap)
$UseAble_Devices = _PcapGetDeviceList() ;[x][7]包含IP
Local $tAdapter = ''
For $i = 0 To UBound($UseAble_Devices) - 1
If $UseAble_Devices[$i][7] =@IPAddress1 Then
$tAdapter = $UseAble_Devices[$i][0]
ExitLoop
EndIf
Next
Global $hPcap
Local $Result,$sTime = TimerInit(),$cTime
Global $DataLen[2][4]
For $i = 0 To 3
$DataLen[0][$i] = 0
$DataLen[1][$i] = 0
Next
Global $WinSock_Direction[300][10]
$WinSock_Direction[0][0] = 0
While 1
If TimerDiff($sTime) >= 998 Then
GUICtrlSetData($Label4,_Flow_Format($WinSock_Direction[0][5])&'/S')
GUICtrlSetData($Label2,_Flow_Format($WinSock_Direction[0][6])&'/S')
$WinSock_Direction[0][5] = 0
$WinSock_Direction[0][6] = 0
$sTime = TimerInit()
EndIf
If $CaptureStatue =1 Then
$cTime = TimerInit()
Do
$WinPcap_Capture=_PcapGetPacket($hPcap)
If IsInt($WinPcap_Capture) Then ExitLoop
$Result = _Decode_Data($WinPcap_Capture[3])
Switch _Deteted_Source($Result[5],$Result[6])
Case 1 ;发送
Switch Number($Result[1])
Case 0x06
;~ If Number($Result[2]) > 65 And Number($Result[2] < 1400) Then
;~ ConsoleWrite(BinaryToString($Result[9]))
;~ EndIf
EndSwitch
_Deteted_ConnetType($Result[6],$Result[2],0)
Case 2 ;接受
Switch Number($Result[1])
Case 0x06
;~ ConsoleWrite('服务器回应...'&@CRLF)
EndSwitch
_Deteted_ConnetType($Result[5],$Result[2],1)
Case 0 ;TNND
EndSwitch
Until TimerDiff($cTime) >= 500
;~ EndIf
EndIf
Sleep(5)
WEnd
Func _Deteted_Source($IP1,$IP2)
If $IP1 = @IPAddress1 Then Return 1
If $IP2 = @IPAddress1 Then Return 2
Return 0
EndFunc
Func _Flow_Format($FlotInt)
If $FlotInt/ 1024 < 5 * 1024 Then
Return Round($FlotInt/1024,1) & ' KB'
Else
Return Round($FlotInt/(1024*1024),1) & " MB"
EndIf
EndFunc
Func _Count_DataLen($Len,$SendorReceive = 0)
$DataLen[0][$SendorReceive] += $Len
$DataLen[0][2+$SendorReceive] += $Len
EndFunc
Func _Deteted_ConnetType($IP,$DataLen,$SendorReceive = 0)
$WinSock_Direction[0][3+$SendorReceive] += $DataLen
$WinSock_Direction[0][5+$SendorReceive] += $DataLen
For $i = 0 To $WinSock_Direction[0][0]
If $IP = $WinSock_Direction[$i][2] Then
$WinSock_Direction[$i][4] = @HOUR&@MIN&@SEC
$WinSock_Direction[$i][5 + $SendorReceive] += $DataLen
Return 1
EndIf
Next
If $WinSock_Direction[0][0] >= UBound($WinSock_Direction) - 2 Then ReDim $WinSock_Direction[$WinSock_Direction[0][0]+500][10]
$WinSock_Direction[0][0] += 1
$WinSock_Direction[$WinSock_Direction[0][0]][1] = @IPAddress1
$WinSock_Direction[$WinSock_Direction[0][0]][2] = $IP
$WinSock_Direction[$WinSock_Direction[0][0]][3] = @HOUR&@MIN&@SEC
$WinSock_Direction[$WinSock_Direction[0][0]][4] = @HOUR&@MIN&@SEC
$WinSock_Direction[$WinSock_Direction[0][0]][5] = 0
$WinSock_Direction[$WinSock_Direction[0][0]][6] = 0
$WinSock_Direction[$WinSock_Direction[0][0]][5+ $SendorReceive] += $DataLen
Return 2
EndFunc
Func _Handle()
Switch @GUI_CtrlId
Case $Button1
$CaptureStatue =1
$hPcap = _PcapStartCapture($tAdapter)
Case $Button2
$CaptureStatue =0
_PcapStopCapture($hPcap)
Case $Button3
_ArrayDisplay($WinSock_Direction)
EndSwitch
EndFunc
Func _Exit()
_PcapStopCapture($hPcap)
_PcapFree()
Exit
EndFunc
Func _Decode_Data($bData,$Mode = 0)
Local $ICMPHeader,$IPHeader,$dData[10];$TCPHeader,$TCPData
;~ $ICMPHeader = BinaryMid($bData,1,14)
$IPHeader = BinaryMid($bData,15,20)
$dData[2] = Dec(Hex(BinaryMid($IPHeader,3,2))) ;数据包长度
$dData[1] = BinaryMid($IPHeader,10,1) ;协议类型 ;0x01 ICMP; 0x02 IGMP; 0x06 TCP; 0x11 UDP
$dData[3] = BinaryMid($IPHeader,13,4) ;源IP,未解码
$dData[4] = BinaryMid($IPHeader,17,4) ;目标IP,未解码
$dData[5] = _DecIPToString(Number($dData[3])) ;源IP
$dData[6] = _DecIPToString(Number($dData[4])) ;目标IP
If $dData[1] = 0x06 Or $dData[1] = 0x11 Then
$dData[7] = Dec(Hex(BinaryMid($bData,35,2)))
$dData[8] = Dec(Hex(BinaryMid($bData,37,2)))
;须加判断读不读取的过程
If $dData[2] > 65 Then
If $dData[1] = 0x06 Then
$dData[9] = BinaryMid($bData,55,$dData[2] - 40 )
Else
$dData[9] = BinaryMid($bData,43,Dec(Hex(BinaryMid($bData,39,2))) - 8 )
EndIf
EndIf
EndIf
Return $dData
EndFunc
Func _DecIPToString($DecIP)
Local $IPString = DllCall("ws2_32.dll", "str", "inet_ntoa", "uint", $DecIP)
If @error Then Return SetError(1, "0.0.0.0")
Return $IPString[0]
EndFunc ;==>_DecIPToString
Func _Set_BinaryStruct($sData,ByRef $sStruct)
Local $iSize = BinaryLen($sData)
$sStruct = DllStructCreate("BYTE["&$iSize+1&"]")
DllStructSetData($sStruct, 1, $sData)
Return DllStructGetPtr($sStruct)
EndFunc
话说Au3中没找到字符串到结构体的函数,本来想用_MemMoveMemory来实现的,不过后来发现,这效率更低了,还是BinaryMid快点。
另外,对上午那个加了Q号的获取: |