lin6051 发表于 2013-4-9 14:36:03

如何'准确'获取流量KB/S

本帖最后由 lin6051 于 2013-4-9 16:44 编辑

测试多个流量监控软件,最准确的是金山卫士

AU3那个在局域网下检测流量还好, 但adsl拨号下测试,速度就很不准确了
而且在测速下载的时候,上传也会跳到10kb/s往上.
adsl拨号情况下,测速400kb/s,它会显示1m/s多

au3那个源码:#include <String.au3>
#include <GUIConstantsEx.au3>
$Form1 = GUICreate("Form1", 192, 67, 445, 376)
$Label1 = GUICtrlCreateLabel("上传速度:", 24, 8, 55, 17)
$Label2 = GUICtrlCreateLabel("0", 88, 8, 100, 17)
$Label3 = GUICtrlCreateLabel("0", 88, 32, 100, 17)
$Label4 = GUICtrlCreateLabel("下载速度:", 24, 32, 55, 17)
GUISetState(@SW_SHOW)
WinSetOnTop ($Form1,"",1)

$_IfTable=_GetIfTable()
Global $_Down=$_IfTable
Global $_UpDate=$_IfTable
AdlibRegister ("_Strat_Time",1000)
While 1
      $nMsg = GUIGetMsg()
      Switch $nMsg
                Case $GUI_EVENT_CLOSE
                        Exit

      EndSwitch
WEnd
Func _Strat_Time()
      $_IfTable=_GetIfTable()
      GUICtrlSetData ($Label2, Round(($_IfTable-$_UpDate)/1024,2)& " Kb")
      GUICtrlSetData ($Label3, Round(($_IfTable-$_Down)/1024,2) & " Kb")
      Global $_Down=$_IfTable
      Global $_UpDate=$_IfTable
EndFunc

Func _GetIfTable()
      $_Return=DllCall("Iphlpapi.dll","long","GetIfTable","ptr",0,"ulong*",0,"int",0)
      $_aBuffer=DllStructCreate("byte[" & $_Return & "]")
      $_Return=DllCall("Iphlpapi.dll","long","GetIfTable","ptr",DllStructGetPtr($_aBuffer),"ulong*",DllStructGetSize($_aBuffer),"int",0)
      $_Number=DllStructCreate("dword",DllStructGetPtr($_aBuffer))
      $_Number=DllStructGetData($_Number,1)
      $_MIB_IFROW="dword" & _StringRepeat(";wchar;dword;byte;dword;byte",$_Number)
      $_MIB_IFTABLE=DllStructCreate($_MIB_IFROW,DllStructGetPtr($_aBuffer))
      Dim $_Table
      For $i=2 To $_Number * 5 Step 5               
                $_Table+=DllStructGetData($_MIB_IFTABLE,$i+3,4)
                $_Table+=DllStructGetData($_MIB_IFTABLE,$i+3,10)
      Next      
      Return $_Table
EndFunc-----------
如何获取宽带连接的流量?
怎么检测宽带连接是否已连接?

lin6051 发表于 2013-4-9 16:04:00

是不是要 减去宽带连接的流量=本地连接的流量

貌似还没找到宽带连接的 流量

xms77 发表于 2013-4-9 19:50:58

回复 1# lin6051
上传流量和下载流量好像正好反了吧?

userdel 发表于 2013-4-9 20:44:09

AdlibRegister 调用函数会不会创建新的线程

mbdnmt 发表于 2013-4-9 23:02:25

路过,坐下来看看

Qokelate 发表于 2013-4-11 11:55:15

GetIfEntry()   可以得到网卡所有进入流量

以秒为单位周期进行统计即是速率

PS:   由于统计周期不一致,所以各个软件统计的速率有小差异是正常现象

feitn 发表于 2013-4-11 13:14:57

好想很强大

lin6051 发表于 2013-4-12 21:38:34

本帖最后由 lin6051 于 2013-4-13 16:27 编辑

找到要调用rasapi32.dll 不知道怎么搞api函数


GetIfEntry 只能显示某网卡的下行流量,没有上行么?

貌似和GetIfTable一个样

lin6051 发表于 2013-4-13 19:31:49

找到了p大的udf,RAS 拨号连接UDF - rasapi
http://www.autoitx.com/thread-17179-1-3.html

修改成这样,简单用用还成
检查adsl是否连接,若连接就 下行流量/2#include <String.au3>
#include <GUIConstantsEx.au3>
#Include <rasapi.au3>
$Form1 = GUICreate("Form1", 192, 67, 445, 376)
$Label1 = GUICtrlCreateLabel("上传速度:", 24, 8, 55, 17)
$Label2 = GUICtrlCreateLabel("0", 88, 8, 100, 17)
$Label3 = GUICtrlCreateLabel("0", 88, 32, 100, 17)
$Label4 = GUICtrlCreateLabel("下载速度:", 24, 32, 55, 17)
GUISetState(@SW_SHOW)
WinSetOnTop ($Form1,"",1)

$_IfTable=_GetIfTable()
Global $_Down=$_IfTable
Global $_UpDate=$_IfTable
AdlibRegister ("_Strat_Time",1000)
While 1
      $nMsg = GUIGetMsg()
      Switch $nMsg
                Case $GUI_EVENT_CLOSE
                        Exit

      EndSwitch
WEnd
Func _Strat_Time()
dim $ras,$notras
$ras=_RasEnumConnections()
if $ras='' then
$notras=1
else
$notras=2
endif
      $_IfTable=_GetIfTable()
      GUICtrlSetData ($Label2, Round(($_IfTable-$_UpDate)/1024*0.96,2)& " Kb")
      GUICtrlSetData ($Label3, Round(($_IfTable-$_Down)/1024*0.96/$notras,2) & " Kb")
      Global $_Down=$_IfTable
      Global $_UpDate=$_IfTable
EndFunc

Func _GetIfTable()
      $_Return=DllCall("Iphlpapi.dll","long","GetIfTable","ptr",0,"ulong*",0,"int",0)
      $_aBuffer=DllStructCreate("byte[" & $_Return & "]")
      $_Return=DllCall("Iphlpapi.dll","long","GetIfTable","ptr",DllStructGetPtr($_aBuffer),"ulong*",DllStructGetSize($_aBuffer),"int",0)
      $_Number=DllStructCreate("dword",DllStructGetPtr($_aBuffer))
      $_Number=DllStructGetData($_Number,1)
      $_MIB_IFROW="dword" & _StringRepeat(";wchar;dword;byte;dword;byte",$_Number)
      $_MIB_IFTABLE=DllStructCreate($_MIB_IFROW,DllStructGetPtr($_aBuffer))
      Dim $_Table
      For $i=2 To $_Number * 5 Step 5               
                $_Table+=DllStructGetData($_MIB_IFTABLE,$i+3,4)
                $_Table+=DllStructGetData($_MIB_IFTABLE,$i+3,10)
      Next      
      Return $_Table
EndFunc

Qokelate 发表于 2013-4-13 22:07:10

回复 9# lin6051


    谁说的,GEtIfEntry得到的是整个网卡的所有流量,包括上下

lin6051 发表于 2013-4-14 10:38:52

本帖最后由 lin6051 于 2013-4-14 10:40 编辑

回复 11# Qokelate

确实可以,昨天用for next 求kb/s 上传就不变$Data1 = _WinAPI_GetIfEntry($index, $Dll)
for $i=1 to 1000 step 1
sleep(1000)
$Data2 = _WinAPI_GetIfEntry($index, $Dll)
ToolTip('下行:'&Round(($Data2-$Data1)/1024,2)&'/上行:'&Round(($Data2-$Data1)/1024,2),120,0)
$Data1 = $Data2
$Data1 = $Data2
next今天用while 就可以..
$Data1 = _WinAPI_GetIfEntry($index, $Dll)
While 1
sleep(1000)
$Data2 = _WinAPI_GetIfEntry($index, $Dll)
ToolTip('下行:'&Round(($Data2-$Data1)/1024,2)&' /上行:'&Round(($Data2-$Data1)/1024,2),120,0)
$Data1=$Data2
$Data1=$Data2
wend不过GetIfEntry貌似不能获取usb和虚拟网卡?
函数是论坛找的 API监视网卡流量lpxx的
http://www.autoitx.com/forum.php?mod=viewthread&tid=37263&highlight=%C1%F7%C1%BF

lin6051 发表于 2013-4-14 10:43:42

;xp sp3   ;不能获取usb,虚拟,禁用的网卡

#Include <Array.au3>

Opt('MustDeclareVars', 1)
Global Const $MIB_IF_TYPE_OTHER = 1
Global Const $MIB_IF_TYPE_ETHERNET_CSMACD = 6
Global Const $MIB_IF_TYPE_ISO88025_TOKENRING = 9
Global Const $MIB_IF_TYPE_PPP = 23
Global Const $MIB_IF_TYPE_SOFTWARE_LOOPBACK = 24
Global Const $MIB_IF_TYPE_ATM = 37
Global Const $MIB_IF_TYPE_IEEE80211 = 71
Global Const $MIB_IF_TYPE_TUNNEL = 131
Global Const $MIB_IF_TYPE_IEEE1394 = 144

Global Const $MIB_IF_ADMIN_STATUS_UP = 1
Global Const $MIB_IF_ADMIN_STATUS_DOWN = 2
Global Const $MIB_IF_ADMIN_STATUS_TESTING = 3

Global Const $MIB_IF_OPER_STATUS_NON_OPERATIONAL = 0
Global Const $MIB_IF_OPER_STATUS_UNREACHABLE = 1
Global Const $MIB_IF_OPER_STATUS_DISCONNECTED = 2
Global Const $MIB_IF_OPER_STATUS_CONNECTING = 3
Global Const $MIB_IF_OPER_STATUS_CONNECTED = 4
Global Const $MIB_IF_OPER_STATUS_OPERATIONAL = 5

Global Const $tagMIB_IFROW = 'wchar Name;dword Index;dword Type;dword Mtu;dword Speed;dword PhysAddrLen;byte PhysAddr;dword AdminStatus;dword OperStatus;dword LastChange;dword InOctets;dword InUcastPkts;dword InNUcastPkts;dword InDiscards;dword InErrors;dword InUnknownProtos;dword OutOctets;dword OutUcastPkts;dword OutNUcastPkts;dword OutDiscards;dword OutErrors;dword OutQLen;dword DescrLen;char Descr'

Global $hParent, $hForm, $Dll, $Msg, $Combo, $Label1, $Label2, $Timer, $Data, $Index = 0, $pIndex = 0, $Adapter = []

$Dll = DllOpen('IPHlpApi.dll')

dim $Data1,$Data2,$index=2      ;修改$index值
$Data1 = _WinAPI_GetIfEntry($index, $Dll)

While 1
sleep(1000)
$Data2 = _WinAPI_GetIfEntry($index, $Dll)
ToolTip('下行:'&Round(($Data2-$Data1)/1024,2)&' /上行:'&Round(($Data2-$Data1)/1024,2),120,0)
$Data1=$Data2
$Data1=$Data2
wend


Func _WinAPI_GetIfEntry($iIndex, $Dll = -1)

    Local $Ret, $Data, $Addr, $Count
    Local $tMIB_IFROW

    If $Dll < 0 Then
      $Dll = 'IPHlpApi.dll'
    EndIf

    $tMIB_IFROW = DllStructCreate($tagMIB_IFROW)
    DllStructSetData($tMIB_IFROW, 2, $iIndex)
    $Ret = DLLCall($Dll, 'dword', 'GetIfEntry', 'ptr', DllStructGetPtr($tMIB_IFROW))
    If (@error) Or ($Ret) Then
      Return SetError($Ret, 0, 0)
    EndIf
    Dim $Data
    $Data = DllStructGetData($tMIB_IFROW, 'Name')
    $Data = $iIndex
    $Data = DllStructGetData($tMIB_IFROW, 'Type')
    $Data = DllStructGetData($tMIB_IFROW, 'Mtu')
    $Data = DllStructGetData($tMIB_IFROW, 'Speed')
    $Count = DllStructGetData($tMIB_IFROW, 'PhysAddrLen')
    $Addr = ''
    For $i = 1 To $Count
      $Addr &= Hex(DllStructGetData($tMIB_IFROW, 'PhysAddr', $i), 2) & '-'
    Next
    $Data = StringTrimRight($Addr, 1)
    $Data = DllStructGetData($tMIB_IFROW, 'AdminStatus')
    $Data = DllStructGetData($tMIB_IFROW, 'OperStatus')
    $Data = DllStructGetData($tMIB_IFROW, 'InOctets')
    $Data = DllStructGetData($tMIB_IFROW, 'InUcastPkts')
    $Data = DllStructGetData($tMIB_IFROW, 'InNUcastPkts')
    $Data = DllStructGetData($tMIB_IFROW, 'InDiscards')
    $Data = DllStructGetData($tMIB_IFROW, 'InErrors')
    $Data = DllStructGetData($tMIB_IFROW, 'InUnknownProtos')
    $Data = DllStructGetData($tMIB_IFROW, 'OutOctets')
    $Data = DllStructGetData($tMIB_IFROW, 'OutUcastPkts')
    $Data = DllStructGetData($tMIB_IFROW, 'OutNUcastPkts')
    $Data = DllStructGetData($tMIB_IFROW, 'OutDiscards')
    $Data = DllStructGetData($tMIB_IFROW, 'OutErrors')
    $Data = StringLeft(DllStructGetData($tMIB_IFROW, 'Descr'), DllStructGetData($tMIB_IFROW, 'DescrLen') - 1)
    Return $Data
EndFunc   ;==>_WinAPI_GetIfEntry

zzbtlc 发表于 2013-4-14 10:46:58

上传流量和下载流量好像正好反了

Qokelate 发表于 2013-4-14 11:40:44

回复 12# lin6051


    XP 没测试,我截图的是Win7 x64的,理论上说虚拟网卡也是可以的, 我截图里面的VMWare就是虚拟网卡而且是禁用状态,禁用的网卡肯定没数据走的(而且我的确也没有在使用), LoopBack 是回环网卡,只有使用127.0.0.1的回环时才有数据,USB没环境,无法测试了
页: [1]
查看完整版本: 如何'准确'获取流量KB/S