Hola,
Con VB.Net 2010 y utilizando System.Net.NetworkInformation obtengo el valor de datos de subida y bajada de mi conexión.
El caso es que me funciona en Vista y Windows7 pero no en XP.
Esta es la función que he utilizado:
Public Class InformationNetWork
Dim Estado As String
Dim DatosRecibidos As String
Dim DatosEnviados As String
Public Function EnumerateNetwok()
Dim properties As System.Net.NetworkInformation.IPGlobalProperties = System.Net.NetworkInformation.IPGlobalProperties.GetIPGlobalProperties()
Dim ipstat As System.Net.NetworkInformation.IPGlobalStatistics = properties.GetIPv4GlobalStatistics()
'//Estado de red
Dim ipv4Stats As System.Net.NetworkInformation.IPv4InterfaceStatistics
ipv4Stats = System.Net.NetworkInformation.NetworkInterface.GetAllNetworkInterfaces(0).GetIPv4Statistics
DatosRecibidos = ipv4Stats.BytesReceived.ToString
DatosEnviados = ipv4Stats.BytesSent.ToString
'//Estado Conexión
Dim ipv4Time As System.Net.NetworkInformation.IPGlobalProperties = System.Net.NetworkInformation.IPGlobalProperties.GetIPGlobalProperties()
Try
Dim n = ipv4Time.GetActiveTcpConnections().Cast(Of System.Net.NetworkInformation.TcpConnectionInformation).First(Function(el) el.State)
Estado = n.State
Catch ex As Exception
Estado = "Desconectado"
End Try
Return 0
End Function
Public Property DatesRecibidos As String
Get
Return DatosRecibidos
End Get
Set(ByVal value As String)
End Set
End Property
Public Property DatesEnviados As String
Get
Return DatosEnviados
End Get
Set(ByVal value As String)
End Set
End Property
End Class
Y para llamarlo hago lo siguiente:
Public Class Form1
Dim Subida As Decimal
Dim Bajada As Decimal
Dim OldSubida As Decimal
Dim OldBajada As Decimal
Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
Dim InfoNet As New InformationNetWork
InfoNet.EnumerateNetwok()
Label4.Text = FormatNumber(((InfoNet.DatesEnviados / 1024 / 1024)), 2) & " MB"
Label5.Text = FormatNumber(((InfoNet.DatesRecibidos / 1024 / 1024)), 2) & " MB"
If OldSubida <> Convert.ToDecimal(FormatNumber(((InfoNet.DatesEnviados / 1024 / 1024)), 2)) Then
Label6.Text = Convert.ToDecimal(FormatNumber(((InfoNet.DatesEnviados / 1024 / 1024)), 2)) + OldSubida & " MB"
Label7.Text = Convert.ToDecimal(FormatNumber(((InfoNet.DatesRecibidos / 1024 / 1024)), 2)) + OldBajada & " MB"
Label9.Text = (Convert.ToDecimal(FormatNumber(((InfoNet.DatesEnviados / 1024 / 1024)), 2)) + OldSubida) + _
(Convert.ToDecimal(FormatNumber(((InfoNet.DatesRecibidos / 1024 / 1024)), 2)) + OldBajada) & " MB"
Subida = Convert.ToDecimal(FormatNumber(((InfoNet.DatesEnviados / 1024 / 1024)), 2)) + OldSubida
Bajada = Convert.ToDecimal(FormatNumber(((InfoNet.DatesRecibidos / 1024 / 1024)), 2)) + OldBajada
End If
End Sub
End Class
Tal vez en XP no este compilado para la versión de .NET que usa el sistema operativo.
1.El motivo de que en un equipo te funcione y en otro no, probablemente se deba a que en esta orden asumes que la primera interfáz de todas que se encuentre (
0) es la que se debe monitorizar, y eso no siempre tiene por que ser así, ya que otros equipos tendrán varias interfaces o simplemente la primera interfáz encontrada no será la que realmente quieras monitorizar.
'//Estado de red
Dim ipv4Stats As IPv4InterfaceStatistics
ipv4Stats = NetworkInterface.GetAllNetworkInterfaces(0).GetIPv4Statistics
Debes comprobar con evaluaciones qué interfáz es la que realmente quieres monitorizar, empezando por filtrar los adaptadores de Internet y verificar cuales de ellos están activos:
If NetworkInterface.GetIsNetworkAvailable() Then
Dim interfaces As NetworkInterface() = NetworkInterface.GetAllNetworkInterfaces()
For Each ni As NetworkInterface In interfaces
If ni.OperationalStatus = OperationalStatus.Up Then
If (ni.NetworkInterfaceType <> NetworkInterfaceType.Tunnel) AndAlso
(ni.NetworkInterfaceType <> NetworkInterfaceType.Loopback) Then
Dim statistics As IPv4InterfaceStatistics = ni.GetIPv4Statistics()
If (statistics.BytesReceived > 0) AndAlso (statistics.BytesSent > 0) Then
' En ste punto tenemos una interfáz de red (Internet) activa...
' ...una de varias que pueden haber conectadas y activas al PC.
End If
End If
End If
Next ni
End If
(Si tienes adaptadores "virtuales" de Ethernet cómo por ejemplo
TAP-Win podría ser un problema con el código que he mostrado, debes omitir esas interfaces claro está)
2. La estructuración en general de la Class InformationNetwork es incorrecta, el dato más importante a tener en cuenta es que defines una función EnumerateNetwok sin un valor de retorno asignado, por ende no es una función como tal, y, no se con que intención, devuelves un 0 que no utilizarás en ninguna evaluación posterior.
Por mencionar algo más, esta evaluación es inecesaria (¿con que intención checkeas una conexión TCP establecida?, de esa manera no se verifica si el adaptador está activo, solo si "X" conexión TCP lo está), el casteo es innecesario, el método lambda también, y no especificas el type de la variable declarada:
CitarDim n = ipv4Time.GetActiveTcpConnections().Cast(Of System.Net.NetworkInformation.TcpConnectionInformation).First(Function(el) el.State)
Dim state As TcpState = ipv4Time.GetActiveTcpConnections.First.State
En general debes limpiar todo el código de esa y la otra class, añade las declaraciones Option apropiadas y posteriormente corrige todos los errores de compilación que te vas a encontrar debido a los malos hábitos de programación que has aplicado en ambas classes.
Option Explicit On
Option Strict On
Option Infer Off
Class
...
End Class
En resumen, simplemente debes asgurarte de que interfáz quieres monitorizar, y complementariamente sigue también las indicaciones del punto
2. para producir un código limpio y evitar malos hábitos que te causarán otros problemas.
Saludos
Una alternativa que puedes utilizar serían los contadores de rendimiento.
He desarrollado la siguiente Class que permite monitorizar el tráfico de una interfáz de red, o incluso el tráfico de un proceso, quiero decir del proceso actual o de un ensamblado .Net externo (en ambos casos para monitorizar el tráfico de un proceso primero es necesario habilitar los contadores de rendimiento en el archivo de configuración de la aplicación, "app.config"), con características básicas para controlar el intervalo de actualización y demás, y con algoritmos simples para medir la velocidad de descarga y subida (los he escrito en un par de horas, dan buenos resultados si se asigna un intervalo de actualización de 1 segundo, son muy mejorables pero por el momento lo he dejado así).
Son dos classes distintas, NetworkTrafficMonitor y ProcessTrafficMonitor, en esta demostración hago uso del monitor del tráfico del proceso actual:
(http://i.imgur.com/jjwSAuH.gif)
Un ejemplo del modo de empleo, el mismo que he utilizado para la app de la imagen GIF:
Imports NetworkUtil
Imports NetworkUtil.NetworkTrafficMonitor
Public NotInheritable Class Form1 : Inherits Form
Dim WithEvents procNetMon As NetworkUtil.ProcessTrafficMonitor
Private Sub Form1_Load() Handles MyBase.Load
Me.procNetMon = New ProcessTrafficMonitor(Process.GetCurrentProcess.Id)
Me.procNetMon.UpdateBehavior = UpdateBehaviorEnum.FireAlwaysAfterTick
Me.procNetMon.UpdateInterval = 1000 ' 1 sec.
Me.procNetMon.Start()
End Sub
Private Sub ProcNetMon_TrafficChanged(ByVal sender As Object, ByVal e As ProcessTrafficMonitor.TrafficChangedEventArgs) _
Handles procNetMon.TrafficChanged
Me.LabelBytesReceived.Text = String.Format("Bytes received: {0} kb", (e.BytesReceived / 1024).ToString("n2"))
Me.LabelDlSpeed.Text = String.Format("DL Speed: {0} kb/sec", (e.DiffBytesReceived / 1024).ToString("n2"))
Me.LabelBytesSent.Text = String.Format("Bytes sent: {0} kb", (e.BytesSent / 1024).ToString("n2"))
Me.LabelUlSpeed.Text = String.Format("UL Speed: {0} kb/sec", (e.DiffBytesSent / 1024).ToString("n2"))
End Sub
Private Sub BtDownloadUrl_Click() Handles BtDownloadUrl.Click
Dim url As String = "http://download.thinkbroadband.com/10MB.zip"
Dim client As New WebClient()
client.DownloadFileAsync(New Uri(url), Path.GetTempFileName())
End Sub
Private Sub BtPauseMon_Click() Handles BtPauseMon.Click
If Me.procNetMon.IsActive Then
Me.procNetMon.Stop()
Else
Me.procNetMon.Start()
End If
End Sub
End Class
La Class NetworkTrafficMonitor, que es en lo que podrías estar interesado, se maneja exactamente de la misma manera, ya que ProcessTrafficMonitor la heredo de esta;
La única diferencia es el constructor, que toma cómo argumento el nombre de una interfáz de red activa.
Ejemplo:
Dim WithEvents netMon As New NetworkTrafficMonitor(NetworkTrafficMonitor.GetAvaliableInterfaceNames.First)
El código fuente lo puedes descargar aquí, simplemente copiar pegar y utilizar:
➢ Network/Process Traffic Monitor in VBNet, By Elektro - PasteBin (http://pastebin.com/Aj0b4QJh)
PD: Si usas la class, te sugiero separar las subclasses que hay definidas en varios archivos.
Diagrama de classes:
(http://i.imgur.com/SC7SUdD.png)
(http://i.imgur.com/GHv0NoT.png)
(http://i.imgur.com/FAc3uK5.png)
(http://i.imgur.com/jNlZSJ5.png)
Espero que les sirva de algo a ti y a los que estén interesados :)
Saludos