Page 1 sur 2
Problème Netstat
Publié : ven. 18/janv./2013 22:48
par Atlante
Hello,
Bon et bien j'essaye de savoir en temps réel le débit network via netstat.
MAIS les résultats sont 3 fois supérieur à la réalité environ, et je ne comprends pas pourquoi.
J'ai passé pas loin d'une dizaine d'heures sur netstat et mes test mais sans succès, du coup je me tourne vers vous :
Code : Tout sélectionner
Global receive.q , send.q, tempReceive.q, tempSend.q, statReceive.q, statSend.q,TempsDepart.q, Text_0, Text_1
receive = 0
send = 0
tempReceive = 0
tempSend = 0
statReceive = 0
statSend = 0
Procedure InitWindow_0()
Window_0 = OpenWindow(#PB_Any, 0, 0, 140, 40, "Debit",#PB_Window_Tool | #PB_Window_BorderLess )
Text_0 = TextGadget(#PB_Any, 0, 0, 140, 20, "Reception :")
Text_1 = TextGadget(#PB_Any, 0, 20, 140, 20, "Emission : ")
StickyWindow(Window_0, 1)
AddSysTrayIcon(1, WindowID(Window_0), LoadImage(0, "D:\Informatique\Pure basic\debit.ico"))
EndProcedure
Procedure netstat(*valeur)
TempsDepart = ElapsedMilliseconds()
requete.l = RunProgram("netstat","-e" ,"", #PB_Program_Open|#PB_Program_Read|#PB_Program_Hide )
If requete
While ProgramRunning(requete)
Output.s = ReadProgramString(requete)
If FindString(Output,"Octets",1)
Output = Right(Output,Len(output)-6)
Output = Trim(Output)
receive = Val(Output) ; premier nombre (reçu)
Output = RemoveString(Output, Str(receive),#PB_String_NoCase)
send = Val(Trim(Output)) ; envoyé
If tempReceive <> 0
statReceive = ((receive - tempReceive)/1024) ; debit ko/s
statSend = ((send - tempSend)/1024) ; debit ko/s
tempReceive = receive
tempSend = send
Else
tempReceive = receive
tempSend = send
EndIf
receive = (receive/1048576) ; total debit en MO
send = (send/1048576) ; total debit en MO
Break
EndIf
Wend
CloseProgram(requete)
EndIf
EndProcedure
Procedure message(*x)
MessageRequester("Debit", "Debit total en reception : " + Str(receive) + "Mo"+Chr(10) +"Debit total en emission : " + Str(send) + "Mo",0)
EndProcedure
InitWindow_0()
Repeat
Delay(50)
event = WindowEvent()
Select event
Case #PB_Event_CloseWindow
a=1
Case #PB_Event_SysTray
Select EventType()
Case PB_EventType_LeftDoubleClick
CreateThread(@message(), 1)
Case #PB_EventType_RightDoubleClick
a=1
EndSelect
EndSelect
TempsEcoule = ElapsedMilliseconds()-TempsDepart
If TempsEcoule > 1000
TempsDepart=0
SetGadgetText(Text_0, "Reception : " + Str(statReceive) + "ko/s")
SetGadgetText(Text_1, "Emission : " + Str(statSend) + "ko/s")
CreateThread(@netstat(), 1)
EndIf
Until a=1
Re: Problème Netstat
Publié : ven. 18/janv./2013 22:50
par Atlante
Dans le cas où personne trouverait je travaille aussi la dessus (ce n'est pas du PB mais du VB) :
Code : Tout sélectionner
Attribute VB_Name = "Internet"
' Les API et les types
Private Declare Function RasEnumConnections Lib "rasapi32" Alias "RasEnumConnectionsA" (ByVal lprasconn As Long, ByVal lpcb As Long, ByVal lpcConnections As Long) As Long
Private Declare Function RasGetConnectionStatistics Lib "rasapi32" (ByVal hRasConn As Long, ByVal lpStatistics As Long) As Long
Private Declare Function InternetGetConnectedStateEx Lib "wininet.dll" (ByRef lpSFlags As Long, ByVal lpszConnectionName As String, ByVal dwNameLen As Long, ByVal dwReserved As Long) As Long
Public Declare Function RegQueryValueEx Lib "advapi32.dll" Alias "RegQueryValueExA" (ByVal hKey As Long, ByVal lpValueName As String, ByVal lpReserved As Long, lpType As Long, lpData As Any, lpcbData As Long) As Long
Public Declare Function RegOpenKeyEx Lib "advapi32.dll" Alias "RegOpenKeyExA" (ByVal hKey As Long, ByVal lpSubKey As String, ByVal ulOptions As Long, ByVal samDesired As Long, phkResult As Long) As Long
Public Declare Function RegOpenKey Lib "advapi32.dll" Alias "RegOpenKeyA" (ByVal hKey As Long, ByVal lpSubKey As String, phkResult As Long) As Long
Public Declare Function RegCloseKey Lib "advapi32.dll" (ByVal hKey As Long) As Long
Private Type RASCONN
dwSize As Long
hRasConn As Long
szEntryName(0 To 256) As Byte
szDeviceType(0 To 16) As Byte
szDeviceName(0 To 128) As Byte
pad As Byte
End Type
Private Type RAS_STATS
dwSize As Long
dwBytesXmited As Long
dwBytesRcved As Long
dwFramesXmited As Long
dwFramesRcved As Long
dwCrcErr As Long
dwTimeoutErr As Long
dwAlignmentErr As Long
dwHardwareOverrunErr As Long
dwFramingErr As Long
dwBufferOverrunErr As Long
dwCompressionRatioIn As Long
dwCompressionRatioOut As Long
dwBps As Long
dwConnectDuration As Long
End Type
' Pour la version du système d'exploitation
Private Declare Function GetVersionEx Lib "kernel32" Alias "GetVersionExA" _
(lpVersionInformation As Any) As Long
Private Type OSVERSIONINFO
OSVSize As Long
dwVerMajor As Long
dwVerMinor As Long
dwBuildNumber As Long
PlatformID As Long
szCSDVersion As String * 128
End Type
Private Stat As RAS_STATS
Private Conn As RASCONN
' UTILISATION :
' c'est très simple, on commence par s'assurer qu'on est connecté avec IsConnected
' puis si on est bien connecté alors on appelle InitConnexionStats
' Ensuite on appelle la fonction qu'on veut
' Puis si on se déconnecte on arrête les relevés (logique), mais si on se
' reconnecte je pense qu'il faut rappeler InitConnexionStats
' _______
' Voilà, un module fait par /MadMatt\, j'ai récupérer des bouts de codes
' \-~°_°~-/
' sur des sources sur VBfrance et j'ai tout mis en ordre
' !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
' !!! à utiliser LIBREMENT, c'est si simple !!!
' !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
' Détecte si on est connecté ou pas
Public Function IsConnected() As Boolean
On Error GoTo Fin
Dim lgLen As Long, lgFlags As Long
Dim stNomConnexion As String
Dim blConnected As Boolean
lgLen = 256
stNomConnexion = Space$(lgLen)
IsConnected = InternetGetConnectedStateEx(lgFlags, stNomConnexion, lgLen, 0&)
Exit Function
Fin:
IsConnected = False
End Function
' Initialise le relevé des informations
Public Function InitConnexionStats() As Boolean
If IsWinNT = False Then InitConnexionStats = True: Exit Function
Dim y As Long, z As Long
Conn.dwSize = Len(Conn)
y = Conn.dwSize
If RasEnumConnections(VarPtr(Conn), VarPtr(y), VarPtr(z)) = 0 Then
Stat.dwSize = Len(Stat)
InitConnexionStats = True
End If
End Function
' Renvoie la vitesse de connexion
Public Function ConnexionSpeed() As Long
On Error GoTo Fin
' Pour Windows XP et autres
If IsWinNT() = True Then
If RasGetConnectionStatistics(Conn.hRasConn, VarPtr(Stat)) = 0 Then
' Pour convertir en octets
ConnexionSpeed = Stat.dwBps / 8
Else
ConnexionSpeed = 0
End If
Else
' Pour les autres
' les variables
Const REG_DWORD = 4
Const HKEY_DYN_DATA = &H80000006
Dim lData, lType, lSize, hKey As Long
Dim Qry As String
' Ouvre la clé
Qry = RegOpenKey(HKEY_DYN_DATA, "PerfStats\StatData", hKey)
' Si ça ne marche pas
If Qry <> 0 Then ConnexionSpeed = 0: Exit Function
' Définit les paramêtres pour la lecture
lType = REG_DWORD
lSize = 4
' Lit la clé
Qry = RegQueryValueEx(hKey, "Dial-Up Adapter\ConnectSpeed", 0, lType, lData, lSize)
' Ferme la clé
RegCloseKey hKey
' Renvoie la valeur
ConnexionSpeed = Int(lData)
End If
Exit Function
Fin:
ConnexionSpeed = 0
End Function
' Renvoie le nombre d'octets reçus (depuis le début de la connexion)
Public Function BytesReceived() As Long
On Error GoTo Fin
If IsWinNT() = True Then
If RasGetConnectionStatistics(Conn.hRasConn, VarPtr(Stat)) = 0 Then
BytesReceived = Stat.dwBytesRcved
Else
BytesReceived = 0
End If
Else
' les variables
Const REG_DWORD = 4
Const HKEY_DYN_DATA = &H80000006
Dim lData, lType, lSize, hKey As Long
Dim Qry As String
' Ouvre la clé
Qry = RegOpenKey(HKEY_DYN_DATA, "PerfStats\StatData", hKey)
' Si ça ne marche pas
If Qry <> 0 Then BytesReceived = 0: Exit Function
' Définit les paramêtres pour la lecture
lType = REG_DWORD
lSize = 4
' Lit la clé
Qry = RegQueryValueEx(hKey, "Dial-Up Adapter\BytesRecvd", 0, lType, lData, lSize)
' Ferme la clé
RegCloseKey hKey
' Renvoie la valeur
BytesReceived = Int(lData)
End If
Exit Function
Fin:
BytesReceived = 0
End Function
' Renvoie le nombre d'octets émis (depuis le début de la connexion)
Public Function BytesEmited() As Long
On Error GoTo Fin
If IsWinNT() = True Then
If RasGetConnectionStatistics(Conn.hRasConn, VarPtr(Stat)) = 0 Then
BytesEmited = Stat.dwBytesXmited
Else
BytesEmited = 0
End If
Else
' les variables
Const REG_DWORD = 4
Const HKEY_DYN_DATA = &H80000006
Dim lData, lType, lSize, hKey As Long
Dim Qry As String
' Ouvre la clé
Qry = RegOpenKey(HKEY_DYN_DATA, "PerfStats\StatData", hKey)
' Si ça ne marche pas
If Qry <> 0 Then BytesEmited = 0: Exit Function
' Définit les paramêtres pour la lecture
lType = REG_DWORD
lSize = 4
' Lit la clé
Qry = RegQueryValueEx(hKey, "Dial-Up Adapter\BytesXmit", 0, lType, lData, lSize)
' Ferme la clé
RegCloseKey hKey
' Renvoie la valeur
BytesEmited = Int(lData)
End If
Exit Function
Fin:
BytesEmited = 0
End Function
' Renvoie le temps depuis lequel l'ordinateur est connecté à internet
Public Function ConnexionDuration() As Long
If IsWinNT = False Then
ConnexionDuration = -1
Exit Function
End If
If RasGetConnectionStatistics(Conn.hRasConn, VarPtr(Stat)) = 0 Then
ConnexionDuration = Stat.dwConnectDuration
End If
End Function
' Renvoie le temps depuis lequel l'ordinateur est connecté à internet
' sous forme rédigée en chaine de caractère
Public Function ConnexionDurationString() As String
If IsWinNT = False Then
ConnexionDurationString = ""
Exit Function
End If
If RasGetConnectionStatistics(Conn.hRasConn, VarPtr(Stat)) = 0 Then
Dim Hour, Minutes, Seconds As Integer
Dim Duration As Long
Duration = Stat.dwConnectDuration
Hour = Int(Duration / 1000 / 60 / 60)
Minutes = Int(Duration / 1000 / 60) - (Hour * 60)
Seconds = Int(Duration / 1000) - (Hour * 60 * 60) - (Minutes * 60)
ConnexionDurationString = Str(Hour) + " H" + Str(Minutes) + " min" + Str(Seconds) + " s"
Else
ConnexionDurationString = ""
End If
End Function
' Renvoie True si l'OS est Windows NT3.5(1), NT4.0, 2000 ou XP
' (pour le relevé des stats)
Public Function IsWinNT() As Boolean
Dim OSInfo As OSVERSIONINFO
OSInfo.OSVSize = Len(OSInfo)
' Récupère la version de l'OS
GetVersionEx OSInfo
' renvoie true si on est sous NT
IsWinNT = (OSInfo.PlatformID = 2)
End Function
Re: Problème Netstat
Publié : sam. 19/janv./2013 0:19
par flaith
Salut Atlante
Tu indique que cela ne correspond pas, par rapport à quoi ?
Si c'est par rapport à l'état de tes connexions réseaux, c'est normal car il 'affiche le nombre de paquets reçus/envoyés donc il faut récupérer la valeur de la ligne "Paquets unicast"
Re: Problème Netstat
Publié : sam. 19/janv./2013 0:22
par Atlante
Hello,
En fait je regarde le nombre d'octet en reception, si je telecharge un fichier mon downloader va me dire 750ko/s mais mon calcul aevc netstat 2400 ko/s...
Re: Problème Netstat
Publié : sam. 19/janv./2013 1:19
par G-Rom
ta conversion est foireuse.
tu reçois un nombre de byte , pas d'octet , tu divises d'abord par 4 pour avoir le nombre d'octet , puis ensuite par 1024 pour avoir les ko.
le résultat sera plus cohérent.
@++
Re: Problème Netstat
Publié : sam. 19/janv./2013 2:00
par Atlante
Pourquoi par 4 ?
Et pourtant c'est bien noté octet dans la console.
Sinon en divisant par 4 le résultat est plus proche de la réalité mais toujours une erreur :
Pour le coup je télécharge a 1300ko/s et mon programme me donne 1100ko/s
Sinon pour la division c'est /1000 et non 1024 (faut oublier c'est plus bon ^^)
++
Re: Problème Netstat
Publié : sam. 19/janv./2013 2:21
par G-Rom
Sinon pour la division c'est /1000 et non 1024 (faut oublier c'est plus bon ^^)
c'est toujours bon.
http://fr.wikipedia.org/wiki/Octet
Pourquoi par 4 ?
parce que

Re: Problème Netstat
Publié : sam. 19/janv./2013 2:28
par Atlante
G-Rom a écrit :
Pourquoi par 4 ?
parce que

Parce que quoi ? Je cherche mais je ne comprends pas pourquoi :
1 octet = 8 bits
Sachant que netstat me revoit de très gros nombre : 1 000 000 000 octet => 1 000 000 Ko il y a pas d division par à faire normalement.
Je comprends pas et je ne trouve pas de documentation ...
Re: Problème Netstat
Publié : sam. 19/janv./2013 4:48
par graph100
juste pour les conversion o -> ko -> mo -> go
C'est nombre sont des puissance de 2
Par définition, un kilo-octet = 2^10 octets = 1024 octets
et de même pour les mo, etc... 2^20 --> 1024 * 1024, etc...
Donc pour convertir des octets en ko : tu divises par 1024.
Ce sont les certaines boites d'informatique, qui, profitant de la méconnaissance du publique, et pour simplifier les affichages (et leurs comptes aussi) mettent des nombres divisés par 1000.
Genre du achète un 500GigaOctets, mais en fait tu achètes : 500 000 000 000 octets, ce qui fait : 465,661 Go réel (regarde sur ton DD)
Il ne faut pas confondre le Giga = 10^9
et le Go = 2^30
Je sais, c'est lourd

Re: Problème Netstat
Publié : sam. 19/janv./2013 12:14
par Backup
......
Re: Problème Netstat
Publié : sam. 19/janv./2013 12:20
par G-Rom
d'ailleurs, je rejoins atlante , je ne comprend pas moi même la division par 4...
Re: Problème Netstat
Publié : sam. 19/janv./2013 12:31
par Atlante
Ouai Dobro autant pour moi j'ai pas fait gaf, nuit très courte ^^
En passant par le cmd cela ne changera rien car j'ai même fait les tests moi même avec la console.
Le problème vient de Netstat pour moi, il doit récupérer plus d'octets que j'en télécharge sur le net.
Peut-être qu'il compte le telechargement via la carte réseau, et après de la carte réseau à 127.0.0.1.
C'est vraiment bizarre cette commande, en plus je ne trouve aucune doc là dessus.
C'est pourtant simple voilà ce que renvoie la commande sans tous les filtres :
Statistiques de l'interface
------- Reçus ..... émis
Octets 32984550 ..... 7818666
Paquets monodiffusion 39120 31398
Paquets non monodiffusion 3609 12860
Rejets 0 0
Erreurs 0 0
Protocoles inconnus 0
J'attends une seconde et je relance la commande.
Du coup je fais : Octets Reçus(de la deuxième fois) - Octets Reçu (la première fois)
Ensuite je divise par 1000 ou 1024 et là j'ai un résultat 3.5 fois supérieur à la réalité en moyenne.
C'est quoi ce délire !
Re: Problème Netstat
Publié : sam. 19/janv./2013 12:41
par kernadec
bonjour
pourquoi par 4 ?
peut être une question de transfert des cartes réseaux qui envoient les données par paquets de 32octets (8*4)
Cordialement
Re: Problème Netstat
Publié : sam. 19/janv./2013 13:26
par Atlante
Allez là on voit bien qu'il y a un problème avec netstat :

Re: Problème Netstat
Publié : sam. 19/janv./2013 13:47
par G-Rom
je ne pense pas qu'il y ai de bug en réalité , ton premier code doit être à peu près bon.
j'en deduis que netstat renvois le nombre d'octet effectivement envoyer sur le réseau , cela inclu la trame tcp 4 / 6 udp , etc... essaye netstat -es
les paquets eux même représente une taille en plus des donnée qu'elles transportent , ton problème viens peu être de là.