| 本帖最后由 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号的获取:
 |