Jump to content


Photo

Network Download/Upload Meter


  • Please log in to reply
59 replies to this topic

#1 Sean

Sean
  • Members
  • 2462 posts

Posted 03 April 2007 - 07:04 AM

It displays the network download/upload KB in progress bar.
I adapted Skan's excellent GUI for HDD Monitor for it:
<!-- m -->http://www.autohotke... ... 890#113890<!-- m -->

I assumed the index of the active network adapter's interface is 2.
And, I made it to truncate the rate at 100KB, which I think can be easily adjustable.

#SingleInstance, Force

Gui, -Caption +Border +AlwaysOnTop +ToolWindow
Gui, Color, EEAA99
Gui, +LastFound
WinSet, TransColor, EEAA99
Gui, Add, Progress,      w100 h10 cGreen -0x1 vDn
Gui, Add, Progress, x+10 w100 h10 cRed   -0x1 vUp
Gui, Show, x780 y3 , NetMeter                  ; Adjust X & Y to suit your screen res

If GetIfTable(tb)
   ExitApp

Loop, % DecodeInteger(&tb)
{
	If DecodeInteger(&tb + 4 + 860 * (A_Index - 1) + 544) < 4 || DecodeInteger(&tb + 4 + 860 * (A_Index - 1) + 516) = 24
	   Continue
	ptr := &tb + 4 + 860 * (A_Index - 1)
	   Break
}

If !ptr
   ExitApp

SetTimer, NetMeter, On, 1000
Return

NetMeter:
DllCall("iphlpapi\GetIfEntry", "Uint", ptr)

dnNew := DecodeInteger(ptr + 552)		; Total Incoming Bytes
upNew := DecodeInteger(ptr + 576)		; Total Outgoing Bytes

dnRate := Round((dnNew - dnOld) / 1024)
upRate := Round((upNew - upOld) / 1024)

GuiControl,, Dn, %dnRate%
GuiControl,, Up, %upRate%

dnOld := dnNew
upOld := upNew
Return


GetIfTable(ByRef tb, bOrder = False)
{
	nSize := 4 + 860 * GetNumberOfInterfaces() + 8
	VarSetCapacity(tb, nSize)
	Return DllCall("iphlpapi\GetIfTable", "Uint", &tb, "UintP", nSize, "int", bOrder)
}

GetIfEntry(ByRef tb, idx)
{
	VarSetCapacity(tb, 860)
	DllCall("ntdll\RtlFillMemoryUlong", "Uint", &tb + 512, "Uint", 4, "Uint", idx)
	Return DllCall("iphlpapi\GetIfEntry", "Uint", &tb)
}

GetNumberOfInterfaces()
{
	DllCall("iphlpapi\GetNumberOfInterfaces", "UintP", nIf)
	Return nIf
}

DecodeInteger(ptr)
{
	Return *ptr | *++ptr << 8 | *++ptr << 16 | *++ptr << 24
}

PS. I believe the following script mimics 'netstat -e', i.e., blindly add up the total downloaded/uploaded bytes of all interfaces.
I recommend it to the users for whom the first script doesn't work, as a temporary work-around.

#SingleInstance, Force

Gui, -Caption +Border +AlwaysOnTop +ToolWindow
Gui, Color, EEAA99
Gui, +LastFound
WinSet, TransColor, EEAA99
Gui, Add, Progress,      w100 h10 cGreen -0x1 vDn
Gui, Add, Progress, x+10 w100 h10 cRed   -0x1 vUp
Gui, Show, x780 y3 , NetMeter                  ; Adjust X & Y to suit your screen res

If GetIfTable(tb)
   ExitApp

SetTimer, NetMeter, On, 1000
Return

NetMeter:
dnNew := 0
upNew := 0

GetIfTable(tb)

Loop, % DecodeInteger(&tb)
{
/*  Include this codes to exclude the loopback interface.
	If DecodeInteger(&tb + 4 + 860 * (A_Index - 1) + 516) = 24
	   Continue
*/
	dnNew += DecodeInteger(&tb + 4 + 860 * (A_Index - 1) + 552)		; Total Incoming Octets
	upNew += DecodeInteger(&tb + 4 + 860 * (A_Index - 1) + 576)		; Total Outgoing Octets
}

dnRate := Round((dnNew - dnOld) / 1024)
upRate := Round((upNew - upOld) / 1024)

GuiControl,, Dn, %dnRate%
GuiControl,, Up, %upRate%

dnOld := dnNew
upOld := upNew
Return


GetIfTable(ByRef tb, bOrder = True)
{
	nSize := 4 + 860 * GetNumberOfInterfaces() + 8
	VarSetCapacity(tb, nSize)
	Return DllCall("iphlpapi\GetIfTable", "Uint", &tb, "UintP", nSize, "int", bOrder)
}

GetIfEntry(ByRef tb, idx)
{
   VarSetCapacity(tb, 860)
   DllCall("ntdll\RtlFillMemoryUlong", "Uint", &tb + 512, "Uint", 4, "Uint", idx)
   Return DllCall("iphlpapi\GetIfEntry", "Uint", &tb)
}

GetNumberOfInterfaces()
{
   DllCall("iphlpapi\GetNumberOfInterfaces", "UintP", nIf)
   Return nIf
}

DecodeInteger(ptr)
{
   Return *ptr | *++ptr << 8 | *++ptr << 16 | *++ptr << 24
}


#2 Timothy

Timothy
  • Guests

Posted 03 April 2007 - 01:22 PM

It doesn't work with mine. I tried both wired and wireless connections and doesn't work with any of them. What can be adjusted to try and make it work with mine?

#3 Grumpy

Grumpy
  • Guests

Posted 03 April 2007 - 01:41 PM

Of course. Just send your computer to Sean, and he will see what is wrong...

#4 Sean

Sean
  • Members
  • 2462 posts

Posted 03 April 2007 - 02:34 PM

It doesn't work with mine. I tried both wired and wireless connections and doesn't work with any of them. What can be adjusted to try and make it work with mine?

What does the following code display?

MsgBox % GetIfTable()


GetIfTable(bOrder = True)
{
	DllCall("iphlpapi\GetNumberOfInterfaces", "UintP", nIf)
	nSize := 4 + 860 * nIf + 8
	VarSetCapacity(tbl, nSize)
	DllCall("iphlpapi\GetIfTable", "Uint", &tbl, "UintP", nSize, "int", bOrder)

	Loop, %nIf%
	      Interfaces .= DecodeInteger(&tbl + 4 + 512 + 860 * (A_Index - 1)) . " : " . DecodeInteger(&tbl + 4 + 516 + 860 * (A_Index - 1)) . " : " . DecodeInteger(&tbl + 4 + 544 + 860 * (A_Index - 1)) . "`n"

	Return Interfaces
}

DecodeInteger(ptr)
{
	Return *ptr | *++ptr << 8 | *++ptr << 16 | *++ptr << 24
}


#5 Timothy

Timothy
  • Guests

Posted 03 April 2007 - 06:26 PM

1 : 24 : 5
65539 : 6 : 5
65540 : 6 : 0
65541 : 6 : 0

#6 bold

bold
  • Members
  • 21 posts

Posted 03 April 2007 - 08:56 PM

It did not work for me also because I have all sorts of virtual network interfaces (for vpn and vmware).

I did the following:

Type the this command in a command prompt and check the output. The output will list all your network interfaces.

ipconfig /all

Check the position of the correct network interface. The first entry is your hostname, below that is the list of network interfaces. For me the sixth entry was the correct one so I replaced the 2 at the end of this line to 6.

DllCall("RtlFillMemory", "Uint", &tb + 512, "Uint", 1, "Uchar", 2)   ; 1-based index of the interface including loopback


#7 Sean

Sean
  • Members
  • 2462 posts

Posted 03 April 2007 - 10:30 PM

1 : 24 : 5
65539 : 6 : 5
65540 : 6 : 0
65541 : 6 : 0

Is this correct? If it's correct, you have to replace

DllCall("RtlFillMemory", "Uint", &tb + 512, "Uint", 1, "Uchar", 2)
with

DllCall("ntdll\RtlFillMemoryUlong", "Uint", &tb + 512, "Uint", 4, "Uint", 65539)


#8 Sean

Sean
  • Members
  • 2462 posts

Posted 03 April 2007 - 10:47 PM

It did not work for me also because I have all sorts of virtual network interfaces (for vpn and vmware).

You figured it out yourself very nicely in spite of my poor explanation. Thanks.

#9 majkinetor

majkinetor
  • Fellows
  • 4511 posts

Posted 04 April 2007 - 08:03 AM

Well, everybody have couple nowdays.
Sean, can you fix it not to depend on this ?

Take one as default and let user choose another one via menu or something ? Or, display all at start and let the user hide unwanted connections.

#10 SKAN

SKAN
  • Administrators
  • 9062 posts

Posted 04 April 2007 - 09:24 AM

Very nice, Sean. :D

BTW, do you know how to ascertain the bytes received & sent ( as shown in LAN status ) ?

#11 Sean

Sean
  • Members
  • 2462 posts

Posted 04 April 2007 - 12:39 PM

Well, everybody have couple nowdays.
Sean, can you fix it not to depend on this ?

I modified it as to detect the active one and then to start monitoring it.
I'm still not sure if it'll always pick out the correct one.

#12 majkinetor

majkinetor
  • Fellows
  • 4511 posts

Posted 04 April 2007 - 12:41 PM

Hej, it works here now :D
Can you close it in function, like:

GetNetworkLoad( networkID="A" )


#13 Sean

Sean
  • Members
  • 2462 posts

Posted 04 April 2007 - 12:45 PM

Very nice, Sean. :D

Thanks! It's your GUI, BTW. :)

BTW, do you know how to ascertain the bytes received & sent ( as shown in LAN status ) ?

I'm not sure if I understand you correctly, but the dnNew/upNew is the total bytes (:which is mostly octets these days) received/sent up to now. Is this the proper answer?

#14 Sean

Sean
  • Members
  • 2462 posts

Posted 04 April 2007 - 01:10 PM

Hej, it works here now :D

Good to know. Thanks.

Can you close it in function, like:

GetNetworkLoad( networkID="A" )

Do you mean like GetIfEntry(ByRef tb, idx)?
It's already there, however, I didn't use it as I couldn't decide whether incorporating offset is good or not.

PS. Oops, I forgot idx.

#15 SKAN

SKAN
  • Administrators
  • 9062 posts

Posted 04 April 2007 - 02:55 PM

BTW, do you know how to ascertain the bytes received & sent ( as shown in LAN status ) ?

I'm not sure if I understand you correctly, but the dnNew/upNew is the total bytes (:which is mostly octets these days) received/sent up to now. Is this the proper answer?


It does not match the bytes sent/recvd shown in my Local Area Connection Status dialog!

I had been wanting to write a bandwidth usage solution for my customised needs, but have never been successful in fetching the exact Sent/Recvd bytes. :( .. Related : Bandwidth Meter/Measurer

I made it to truncate the rate at 100KB, which I think can be easily adjustable


FYI:

I have a rather slow ADSL connection On Ethernet in W2K OS. The progress bar does not budge until I remove the "/ 1024"

The current version automatically selects.. :!: :D For the previous version I had to alter the RtlFill... to 1 instead of 2.

Thanks .. :)