Class XNET {} - Monitor Network Interface

Post your working scripts, libraries and tools for AHK v1.1 and older
User avatar
SKAN
Posts: 1551
Joined: 29 Sep 2013, 16:58

Class XNET {} - Monitor Network Interface

11 Sep 2014, 18:01

Disclaimer: I am new to Custom objects. This is my first one. May the knowledgeable ones please let me know if/where I am fundamentally wrong.

Credits:
Thanks to Learning One and jethrow for posting simple examples here.
Thanks to the nice example available in Doc. Initially terrifying (for a noob), but very helpful once I managed to understand the concept.
Sincere thanks to HotKeyIt for helping me to get started: Ask for Help » Binary data in Object

Class XNET - Requires Windows Vista and greater.

Basic usage example:

Image

Code: Select all

#NoEnv
#Warn

Net := new XNET( True ) ; Auto select interface ( interface used  by web browsers )

Gui +AlwaysOnTop -MaximizeBox -Minimizebox +Owner
Gui, Font, S10, Arial
Gui, Add, Text, xm   h25 w80  0x200 Right, Transmitted
Gui, Add, Edit, x+20 hp  w120       Right ReadOnly -Tabstop  vTX
Gui, Add, Text, xm   h25 w80  0x200 Right, BPS
Gui, Add, Edit, x+20 hp  w120       Right ReadOnly -Tabstop  vTXBPS
Gui, Add, Text, xm   h25 w80  0x200 Right, Received
Gui, Add, Edit, x+20 hp  w120       Right ReadOnly -Tabstop  vRX
Gui, Add, Text, xm   h25 w80  0x200 Right, BPS
Gui, Add, Edit, x+20 hp  w120       Right ReadOnly -Tabstop  vRXBPS
Gui, Add, StatusBar
Gui, Show,, % Net.Alias
SetTimer, Update, 200

Update:
  Net.Update()
  GuiControl,, TX,    % Net.Tx
  GuiControl,, TXBPS, % Net.TxBPS
  GuiControl,, RX,    % Net.Rx
  GuiControl,, RXBPS, % Net.RxBPS
  SB_SetText( A_Space Net.State )
Return

GuiClose:
GuiEscape:
  ExitApp
 
#Include XNET.ahk
Manually selecting Net Interface ( i.e, the interface to be monitored )

Image

As seen in network connections dailog, I am simultaneousuly connected to internet via ADSL2 as well as a Dialup. Web browser would use Dialup until I disconnect, and then fallback to ADSL2.
By default XNET reads data from InUcastOctets and OutUcastOctets ( the default for Ethernet ), whereas for my Dialup the data is available only in InOctets and OutOctets. So, I call SetDataOffsets method to manually set the offsets.

Code: Select all

Net := new XNET( False ) ; do not auto select interface
Net.Alias := "Airtel 2G"
Net.SetDataOffsets( 1208, 1280 )  ; Manually set offsets to InOctets and OutOctets
.. read/process data
Note: The "Interface to be monitored" can be switched between at runtime, for example, like: Net.Alias := "Airtel 2G" and Net.Alias := "Local Area Connection"
To switch between interfaces you may SET any of the following members: InterfaceIndex, InterfaceLuid, InterfaceGuid, Alias and Description.
Example:

Code: Select all

Adapter := new XNET( False )
Adapter.Description := "Realtek PCIe GBE Family Controller"
You may retrieve any member from MIB_IFROW2 STRUCTURE by its name

Code: Select all

Adapter := new XNET( False )
Adapter.Description := "Realtek PCIe GBE Family Controller" ; Select Adapter
MACAddress := Adapter.PhysicalAddress ; Retrieve MACAddress
The following snippet will list all available interfaces of your computer:
Image

Code: Select all

#SingleInstance, Force
#Include XNET.ahk
#Warn

nIfCount := 0,  List := ""
DllCall( "iphlpapi\GetNumberOfInterfaces", "PtrP",nIfCount )

NET := new XNET( False )  

Loop %nIfCount% 
  NET.InterfaceIndex := A_Index
, List .= "InterfaceIndex  :  " NET.InterfaceIndex  "`n"
       .  "InterfaceLuid   :  " NET.InterfaceLuid   "`n"
       .  "InterfaceGuid   :  " NET.InterfaceGuid   "`n"
       .  "Alias           :  " NET.Alias           "`n"
       .  "Description     :  " NET.Description   "`n`n"

Gui, Font, S10, Courier New
Gui, Add, Edit, w640 h480 -Wrap hwndhEdit, %List%
Gui, Show,, Network Interfaces (%nIfCount%)
DllCall( "SendMessage", "Ptr",hEdit, "UInt",0xB1, "Ptr",0 , "Ptr",0 ) ; EM_SETSEL
Return

GuiEscape:
GuiClose:
 ExitApp
Some useful related functions: FormatBytesEx(), Mean() and QueueVal(), XGraph()

Wrapper:

Code: Select all

/*   __    __  __          __ __       __    __                 _       __                   
    / /_  / /_/ /_____  _ / // /____ _/ /_  / /________________(_)___  / /_ ____  _______
   / __ \/ __/ __/ __ \(_) // // __ '/ __ \/ //_/ ___/ ___/ __/ / __ \/ __// __ \/ __/ _ \
  / / / / /_/ /_/ /_/ / / // // /_/ / / / / ,< (__  ) /__/ / / / /_/ / /__/ /_/ / / / // / 
 /_/ /_/\__/\__/ .___(_) // / \__,_/_/ /_/_/|_/____/\___/_/ /_/ .___/\__(_)____/_/  \__ /  
              /_/     /_//_/                                 /_/                   (___/   
 
  http://ahkscript.org/boards/viewtopic.php?&t=4542
 
  XNET is a Class wrapper that simplifies access to MIB_IFROW2 structure.
  XNET helps in monitoring network connection and data.
__________________________________________________________________________________________

  STRUCTURE MIB_IFROW2 ( MSDN http://goo.gl/Fufv7m )
  ----------------------------------------------------------------------------------------
  Offset Size Type   Description                     Comment
  ----------------------------------------------------------------------------------------
  0        8  INT64  InterfaceLuid 
  8        4  UINT   InterfaceIndex
  12      16  GUID   InterfaceGuid
  28     514  WSTR   Alias   
  542    514  WSTR   Description                     Friendly name
  1056     4  UINT   PhysicalAddressLength
  1060    32  BYTE   PhysicalAddress                 MAC address
  1092    32  BYTE   PermanentPhysicalAddress        MAC address
  1124     4  UINT   Mtu
  1128     4  UINT   Type ( IFTYPE )
  1132     4  UINT   TunnelType
  1136     4  UINT   MediaType
  1140     4  UINT   PhysicalMediumType
  1144     4  UINT   AccessType   
  1148     4  UINT   DirectionType
  1152     4  UINT   InterfaceAndOperStatusFlags
  1156     4  UINT   OperStatus
  1160     4  UINT   AdminStatus
  1164     4  UINT   MediaConnectState
  1168    16  GUID   NetworkGuid
  1184     4  UINT   ConnectionType
  1188     4  ----   ----                            Padding for x64 alignment
  1192     8  UINT64 TransmitLinkSpeed
  1200     8  UINT64 ReceiveLinkSpeed
  1208     8  UINT64 InOctets                        Received Bytes
  1216     8  UINT64 InUcastPkts
  1224     8  UINT64 InNUcastPkts
  1232     8  UINT64 InDiscards
  1240     8  UINT64 InErrors
  1248     8  UINT64 InUnknownProtos
  1256     8  UINT64 InUcastOctets                   Received bytes
  1264     8  UINT64 InMulticastOctets
  1272     8  UINT64 InBroadcastOctets
  1280     8  UINT64 OutOctets                       Sent Bytes
  1288     8  UINT64 OutUcastPkts
  1296     8  UINT64 OutNUcastPkts
  1304     8  UINT64 OutDiscards
  1312     8  UINT64 OutErrors
  1320     8  UINT64 OutUcastOctets                  Sent Bytes
  1328     8  UINT64 OutMulticastOctets
  1336     8  UINT64 OutBroadcastOctets
  1344     8  UINT64 OutQLen
  ----------------------------------------------------------------------------------------
  1352 bytes in total + 16 extra bytes follow
  ----------------------------------------------------------------------------------------
  1352     8  PTR    Pointer to InUcastOctets
  1360     8  PTR    Pointer to OutUcastOctets             
  ----------------------------------------------------------------------------------------
*/


Class XNET  ;             By SKAN,  http://goo.gl/zNmlqm,  CD:27/Aug/2014 | MD:12/Sep/2014
{

    __New( AutoIF := True ) 
    { 
        Local IfIndex := 0
        this.hModule := DllCall( "LoadLibrary", "Str","Iphlpapi.dll", "Ptr" )
        this.SetCapacity( "MIB_IF_ROW2", 1368 ),  this.ZeroFill( 1368 )
        this.SetDataOffsets(), this.GetTime( True )
        DllCall( "iphlpapi\GetBestInterface", "Ptr",0, "PtrP",IfIndex )
        If ( AutoIF and IfIndex )  
          NumPut( IfIndex, this.GetAddress( "MIB_IF_ROW2" ) + 8, "UInt" )
        , this.Update( True )
    }     

    ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

    __Delete() 
    { 
        DllCall( "FreeLibrary", "Ptr",this.hModule ) 
    }

    ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

    __Set( Member, Value ) 
    {
        Local pData := this.GetAddress( "MIB_IF_ROW2" ),  nIfCount := 0,  Found := 0 
      
        If ( Member = "InterfaceLuid" )
        {
             this.ZeroFill( 12 )
             this.NET_LUID( Value )
        }   


        If ( Member = "InterfaceIndex" )
        {  
             this.ZeroFill( 12 )
             NumPut( Value, pData+8, "UInt" )
        }  
       

        If ( Member = "InterfaceGuid" )
        {  
             this.ZeroFill( 12 )
             DllCall( "ole32\CLSIDFromString", "WStr",Value, "Ptr",pData+12 )
             DllCall( "iphlpapi\ConvertInterfaceGuidToLuid", "Ptr",pData+12, "Ptr",pData )
        }  
 

        If ( Member = "Alias" )
        {  
             this.ZeroFill( 12 )
             DllCall( "iphlpapi\ConvertInterfaceAliasToLuid", "WStr",Value,  "Ptr",pData )
        }   


        If ( Member = "Description" ) 
        {
             DllCall( "iphlpapi\GetNumberOfInterfaces", "PtrP",nIfCount )
             Loop % ( nIfCount ) 
             {
                 NumPut( A_Index, NumPut( 0, pData+0, "Int64" ), "UInt" )
                 DllCall( "iphlpapi\GetIfEntry2", "Ptr",pData )
                 If ( StrGet( pData+542, "UTF-16" ) = Value and ( Found := True ) )
                     Break 
             }

             ErrorLevel := ( not Found ) ? this.ZeroFill( 12 ) : ""
        }

    If Member in InterfaceLuid,InterfaceIndex,InterfaceGuid,Alias,Description
       Return this.Update( True ) ? Value : ""
    }

    ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

    __Get( Member ) 
    {
        Local pData := this.GetAddress( "MIB_IF_ROW2" )

        IfEqual, Member, InterfaceLuid,               Return this.NET_LUID()
        IfEqual, Member, InterfaceIndex,              Return NumGet( pData+  8,   "UInt" )
        IfEqual, Member, Alias,                       Return StrGet( pData+ 28, "UTF-16" )
        IfEqual, Member, Description,                 Return StrGet( pData+542, "UTF-16" )
        IfEqual, Member, InterfaceGuid,               Return this.GUID( 12 ) 
        IfEqual, Member, PhysicalAddress,             Return this.MAC( 1060 )
        IfEqual, Member, PermanentPhysicalAddress,    Return this.MAC( 1092 )
        IfEqual, Member, Mtu,                         Return NumGet( pData+1124,  "UInt" )
        IfEqual, Member, Type,                        Return NumGet( pData+1128,  "UInt" )
        IfEqual, Member, TunnelType,                  Return NumGet( pData+1132,  "UInt" )
        IfEqual, Member, MediaType,                   Return NumGet( pData+1136,  "UInt" )
        IfEqual, Member, PhysicalMediumType,          Return NumGet( pData+1140,  "UInt" )
        IfEqual, Member, AccessType,                  Return NumGet( pData+1144,  "UInt" )
        IfEqual, Member, DirectionType,               Return NumGet( pData+1148,  "UInt" )
        IfEqual, Member, InterfaceAndOperStatusFlags, Return NumGet( pData+1152,  "UInt" )
        IfEqual, Member, OperStatus,                  Return NumGet( pData+1156,  "UInt" )
        IfEqual, Member, AdminStatus,                 Return NumGet( pData+1160,  "UInt" )
        IfEqual, Member, MediaConnectState,           Return NumGet( pData+1164,  "UInt" )
        IfEqual, Member, NetworkGuid,                 Return this.GUID( 1168 )
        IfEqual, Member, ConnectionType,              Return NumGet( pData+1184,  "UInt" )
        IfEqual, Member, TransmitLinkSpeed,           Return NumGet( pData+1192, "Int64" )
        IfEqual, Member, ReceiveLinkSpeed,            Return NumGet( pData+1200, "Int64" )
        IfEqual, Member, InOctets,                    Return NumGet( pData+1208, "Int64" )
        IfEqual, Member, InUcastPkts,                 Return NumGet( pData+1216, "Int64" )
        IfEqual, Member, InNUcastPkts,                Return NumGet( pData+1224, "Int64" )
        IfEqual, Member, InDiscards,                  Return NumGet( pData+1232, "Int64" )
        IfEqual, Member, InErrors,                    Return NumGet( pData+1240, "Int64" )
        IfEqual, Member, InUnknownProtos,             Return NumGet( pData+1248, "Int64" )
        IfEqual, Member, InUcastOctets,               Return NumGet( pData+1256, "Int64" )
        IfEqual, Member, InMulticastOctets,           Return NumGet( pData+1264, "Int64" )
        IfEqual, Member, InBroadcastOctets,           Return NumGet( pData+1272, "Int64" )
        IfEqual, Member, OutOctets,                   Return NumGet( pData+1280, "Int64" )
        IfEqual, Member, OutUcastPkts,                Return NumGet( pData+1288, "Int64" )
        IfEqual, Member, OutNUcastPkts,               Return NumGet( pData+1296, "Int64" )
        IfEqual, Member, OutDiscards,                 Return NumGet( pData+1304, "Int64" )
        IfEqual, Member, OutErrors,                   Return NumGet( pData+1312, "Int64" )
        IfEqual, Member, OutUcastOctets,              Return NumGet( pData+1320, "Int64" )
        IfEqual, Member, OutMulticastOctets,          Return NumGet( pData+1328, "Int64" )
        IfEqual, Member, OutBroadcastOctets,          Return NumGet( pData+1336, "Int64" )
        IfEqual, Member, OutQLen,                     Return NumGet( pData+1344, "Int64" )

    }

    ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

    InterfaceAndOperStatusFlags( SubMember := "" ) 
    {
        Local pData := this.GetAddress( "MIB_IF_ROW2" )
            , Flags := NumGet( pData+1152, "UInt" )
      
        IfEqual, SubMember, HardwareInterface,        Return ( Flags >> 0 & 1 )
        IfEqual, SubMember, FilterInterface,          Return ( Flags >> 1 & 1 )
        IfEqual, SubMember, ConnectorPresent,         Return ( Flags >> 2 & 1 )
        IfEqual, SubMember, NotAuthenticated,         Return ( Flags >> 3 & 1 )
        IfEqual, SubMember, NotMediaConnected,        Return ( Flags >> 4 & 1 )
        IfEqual, SubMember, Paused,                   Return ( Flags >> 5 & 1 )
        IfEqual, SubMember, LowPower,                 Return ( Flags >> 6 & 1 )
        IfEqual, SubMember, EndPointInterface,        Return ( Flags >> 7 & 1 )                  

    Return -1
    }

    ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

    Update( Reset := 0 ) 
    {
        Local pData := this.GetAddress( "MIB_IF_ROW2" ), MS, OldTx, OldRx, Tx, Rx, MCS  
        MS    := this.GetTime( Reset )
        
        OldTx := NumGet( NumGet( pData+1360 ), "Int64" )  
        OldRx := NumGet( NumGet( pData+1352 ), "Int64" )

        If ErrorLevel := DllCall( "iphlpapi\GetIfEntry2", "Ptr",pData )
           Return 0,  this.ZeroFill()

        this.Tx    := Tx := NumGet( NumGet( pData+1360 ), "Int64" )  
        this.Rx    := Rx := NumGet( NumGet( pData+1352 ), "Int64" )
        this.TxBPS := Round( ( ( Tx-OldTx ) / 1000 ) / ( MS/1000 ) * 1000 ) 
        this.RxBPS := Round( ( ( Rx-OldRx ) / 1000 ) / ( MS/1000 ) * 1000 ) 

        MCS := NumGet( pData+1164,"UInt" )
        this.State := ( MCS=1 ? "Connected" : MCS=2 ? "Disconnected" : "Unknown" )
      
    Return True     
    }

    ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -    

    SetDataOffsets( In := 1256, Out := 1320 ) {
         Local pData := this.GetAddress( "MIB_IF_ROW2" )
         NumPut( pData + In, pData + 1352 ), NumPut( pData + Out, pData + 1360 )  
    }
       
    ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -    

    ZeroFill( Bytes := 1352, FillChar := 0 ) {
        Local pData := this.GetAddress( "MIB_IF_ROW2" )
        DllCall( "RtlFillMemory", "Ptr",pData, "Ptr",Bytes, "UChar",FillChar )
    }


    ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

    NET_LUID( sLUID := "" ) 
    {
        Local pData := this.GetAddress( "MIB_IF_ROW2" ), AFI := "", L := 0 

        If ( not SLUID ) 
        {
           SetFormat, IntegerFast, % "H" ( AFI := A_FormatInteger )
           sLUID := SubStr( 0x1000000 | ( NumGet( pData+0, "UInt" ) & 0xFFFFFF ), -5 ) "-" 
                 .  SubStr( 0x1000000 | ( NumGet( pData+3, "UInt" ) & 0xFFFFFF ), -5 ) "-"
                 .  SubStr( 0x1000000 |   NumGet( pData+6, "UShort" ), -3 )
           SetFormat, IntegerFast, %AFI%

        Return "{" sLUID "}"
        }

        StringSplit, L, sLUID, -, {}%A_Space%
        NumPut( "0x" L1, pData+0, "UInt" )
        NumPut( "0x" L2, pData+3, "UInt" )
        NumPut( "0x" L3, pData+6, "UShort" )  

    Return NumGet( pData+0, "Int64" )  
    }

    ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

    MAC( Offset := 1092 ) 
    {
        Local pData := this.GetAddress( "MIB_IF_ROW2" ),  PhysAddr := "" 
        SetFormat, IntegerFast, % "H" ( AFI := A_FormatInteger )
        Loop % NumGet( pData + 1056, "UInt" )
           PhysAddr .= "-" SubStr( 0x100 | NumGet( pData+OffSet+A_Index-1, "UChar" ), -1 ) 
        SetFormat, IntegerFast, %AFI%

    Return SubStr( PhysAddr, 2 )  
    }

    ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

    GUID( Offset := 12 ) 
    {
        Local pData := this.GetAddress( "MIB_IF_ROW2" ) 
        VarSetCapacity( GUID,80,0 )
        DllCall( "ole32\StringFromGUID2", "Ptr",pData + Offset, "Ptr",&GUID, "Int",39 ) 

    Return StrGet( &GUID, "UTF-16" )
    }
 
    ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

    GetTime( Reset := 0 )  
    {
        Local T1601 := 0, OldTime := 0

        DllCall( "GetSystemTimeAsFileTime", "Int64P",T1601 ), T1601 //= 10000
        OldTime := this.Time, this.Time := T1601

    Return Reset ? ( this.Time := T1601 ) - T1601 : ( this.Time - OldTime )  
    }

    ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
}   ;                                                                          end of XNET
;= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = 
This post is incomplete... I will update later :)
My Scripts and Functions: V1  V2
User avatar
jNizM
Posts: 3183
Joined: 30 Sep 2013, 01:33
Contact:

Re: Class XNET {} - Monitor Network Interface

12 Sep 2014, 00:52

Hey SKAN
Thank you for you n1 work =)

I know you like one-lines like this
IfEqual, Member, TunnelType, Return NumGet( pData+1132, "UInt" )
But isnt it better to use if (var = value) since IfXXX is one of these removed commands in future?

Same for:
If Member in InterfaceLuid,InterfaceIndex,InterfaceGuid,Alias,Description
==> if (Member ~= "InterfaceLuid|InterfaceIndex|InterfaceGuid|Alias|Description")

Ref-links:
- v2-changes
- Topic: v2 removed commands
[AHK] v2.0.5 | [WIN] 11 Pro (Version 22H2) | [GitHub] Profile
User avatar
SKAN
Posts: 1551
Joined: 29 Sep 2013, 16:58

Re: Class XNET {} - Monitor Network Interface

12 Sep 2014, 10:03

jNizM wrote:Thank you for you n1 work =)
Welcome!.... and sorry! A bit late... :)
I know you like one-lines like this
IfEqual, Member, TunnelType, Return NumGet( pData+1132, "UInt" )
But isnt it better to use if (var = value) since IfXXX is one of these removed commands in future?
In this case, it is not about short code... I find it highly readable, especially while writing the code. I had the idea of changing it, once I had it working, but felt lazy. :)
I am aware of V2 changes..
Same for:
If Member in InterfaceLuid,InterfaceIndex,InterfaceGuid,Alias,Description
==> if (Member ~= "InterfaceLuid|InterfaceIndex|InterfaceGuid|Alias|Description")
I like it. Thanks :)
User avatar
Chef
Posts: 50
Joined: 14 Nov 2013, 13:01

Re: Class XNET {} - Monitor Network Interface

13 Sep 2014, 23:35

Nice SKAN,

Is the timer in your test script supposed to detect changes to the network?
I tested it quickly, network connection status displays correctly on script startup (connected or not), but fails to detect further changes to connection status.
User avatar
SKAN
Posts: 1551
Joined: 29 Sep 2013, 16:58

Re: Class XNET {} - Monitor Network Interface

14 Sep 2014, 10:23

Chef wrote:Is the timer in your test script supposed to detect changes to the network?
Yes. Should be equivalent of "Media State" shown in Local Area Connection Status dialog.
An alternate is Net.InterfaceAndOperStatusFlags( "NotMediaConnected" )
User avatar
SKAN
Posts: 1551
Joined: 29 Sep 2013, 16:58

Re: Class XNET {} - Monitor Network Interface

14 Sep 2014, 21:49

Finding connection duration:

Image

The following will return a UTC timestamp + Offset in minutes like: 20140915060144.000000+330

Code: Select all

Adapter := "Realtek PCIe GBE Family Controller"
queryEnum := ComObjGet( "winmgmts:" ).ExecQuery( "Select * from Win32_NetworkAdapterConfiguration "
                      . "where Description = '" Adapter "'" )._NewEnum()
If queryEnum[ NAC ]
MsgBox % NAC.DHCPLeaseObtained
Dsalomon
Posts: 22
Joined: 02 Mar 2021, 23:01

Re: Class XNET {} - Monitor Network Interface

28 Sep 2021, 04:05

@SKAN

like change from BPS to Mbps, I tried to do the multiplications but it doesn't work, thanks.

PD: by the way I finally understood how it works and it keeps my network always up, thanks for your work
User avatar
jNizM
Posts: 3183
Joined: 30 Sep 2013, 01:33
Contact:

Re: Class XNET {} - Monitor Network Interface

28 Sep 2021, 04:39

1 Mbps = 1000000 bps
So you have to divide. But I would not recommend to use Mbps. Better use kbps if you want a higher value.

And I would recommend to do it just if the bps value is above a specific value (like bps > 1000 than go to kbps)

You can also use his function to convert -> viewtopic.php?f=6&t=3567#p18352
[AHK] v2.0.5 | [WIN] 11 Pro (Version 22H2) | [GitHub] Profile

Return to “Scripts and Functions (v1)”

Who is online

Users browsing this forum: No registered users and 241 guests