¿Cómo verifico una conexión de red?

Respuestas:

153

Puede verificar una conexión de red en .NET 2.0 usando GetIsNetworkAvailable():

System.Net.NetworkInformation.NetworkInterface.GetIsNetworkAvailable()

Para monitorear cambios en la dirección IP o cambios en la disponibilidad de la red, use los eventos de la clase NetworkChange :

System.Net.NetworkInformation.NetworkChange.NetworkAvailabilityChanged
System.Net.NetworkInformation.NetworkChange.NetworkAddressChanged
Trigo Mitch
fuente
9
¿Esto se ocupa de la "disponibilidad limitada"?
tofutim
Esto no siempre funciona en WPF. Algunas computadoras portátiles devuelven falso y otras verdaderas
krilovich
¿Esto realmente funciona? ¡Acabo de escribir esta línea y apago mi enrutador y todavía devuelve verdadero!
Mushfiq
1
NetworkInterface.GetIsNetworkAvailable()ha sido muy poco confiable en mi aplicación (.NET 4.5, Windows 10), especialmente cuando se ejecuta en una máquina virtual. Manejar los eventos de NetworkAvailabilityChangedha sido confiable.
eskimwier
Eso no es confiable. leer stackoverflow.com/a/25779403/2377343
T.Todua
174

La respuesta marcada es 100% buena, sin embargo, hay ciertos casos en los que el método estándar es engañado por tarjetas virtuales (caja virtual, ...). También suele ser deseable descartar algunas interfaces de red en función de su velocidad (puertos serie, módems, ...).

Aquí hay un fragmento de código que busca estos casos:

    /// <summary>
    /// Indicates whether any network connection is available
    /// Filter connections below a specified speed, as well as virtual network cards.
    /// </summary>
    /// <returns>
    ///     <c>true</c> if a network connection is available; otherwise, <c>false</c>.
    /// </returns>
    public static bool IsNetworkAvailable()
    {
        return IsNetworkAvailable(0);
    }

    /// <summary>
    /// Indicates whether any network connection is available.
    /// Filter connections below a specified speed, as well as virtual network cards.
    /// </summary>
    /// <param name="minimumSpeed">The minimum speed required. Passing 0 will not filter connection using speed.</param>
    /// <returns>
    ///     <c>true</c> if a network connection is available; otherwise, <c>false</c>.
    /// </returns>
    public static bool IsNetworkAvailable(long minimumSpeed)
    {
        if (!NetworkInterface.GetIsNetworkAvailable())
            return false;

        foreach (NetworkInterface ni in NetworkInterface.GetAllNetworkInterfaces())
        {
            // discard because of standard reasons
            if ((ni.OperationalStatus != OperationalStatus.Up) ||
                (ni.NetworkInterfaceType == NetworkInterfaceType.Loopback) ||
                (ni.NetworkInterfaceType == NetworkInterfaceType.Tunnel))
                continue;

            // this allow to filter modems, serial, etc.
            // I use 10000000 as a minimum speed for most cases
            if (ni.Speed < minimumSpeed)
                continue;

            // discard virtual cards (virtual box, virtual pc, etc.)
            if ((ni.Description.IndexOf("virtual", StringComparison.OrdinalIgnoreCase) >= 0) ||
                (ni.Name.IndexOf("virtual", StringComparison.OrdinalIgnoreCase) >= 0))
                continue;

            // discard "Microsoft Loopback Adapter", it will not show as NetworkInterfaceType.Loopback but as Ethernet Card.
            if (ni.Description.Equals("Microsoft Loopback Adapter", StringComparison.OrdinalIgnoreCase))
                continue;

            return true;
        }
        return false;
    }
Simón Mourier
fuente
17
esto es correcto y merece muchos votos positivos: descubrí que el evento NetworkAvailabilityChanged mencionado en la respuesta aceptada no se activa de manera confiable, lo que probablemente sea causado por adaptadores virtuales como se menciona en esta respuesta
Marek
1
+1 para la comprobación adicional de máquinas virtuales. Me encontré con este caso ayer. Pero sigo pensando que esto no funciona con "Hype-V", porque no tienen "virtual" en su nombre.
Herdo
3
@Herdo: sí, el código no es perfecto y no creo que pueda haber nada perfecto en un mundo virtual. Pero puedes mejorarlo.
Simon Mourier
@SimonMourier Tienes razón. Solo quería señalar que, si alguien sigue siendo verdadero, si no hay conexión -> Esto podría ser un problema :)
Herdo
1
@noelicus - En los proyectos en los que he estado trabajando hasta ahora, he implementado un sistema de sondeo / monitoreo periódico (solicitudes HTTP GET simples porque estaba apuntando a un servidor web) que genera eventos cuando el servidor se detecta como "inactivo" (no accesible por HTTP) o "arriba" (accesible de nuevo). En el caso general, puede definir qué significa "confiable" en su caso e implementar una lógica similar.
Simon Mourier
9

Microsoft Windows Vista y 7 utilizan la técnica NCSI (Indicador de estado de conectividad de red):

  1. NCSI realiza una búsqueda de DNS en www.msftncsi.com, luego solicita http://www.msftncsi.com/ncsi.txt . Este archivo es un archivo de texto sin formato y contiene solo el texto ' Microsoft NCSI '.
  2. NCSI envía una solicitud de búsqueda de DNS para dns.msftncsi.com. Esta dirección DNS debería resolverse en 131.107.255.255. Si la dirección no coincide, se asume que la conexión a Internet no funciona correctamente.
Saleh Rahimzadeh
fuente
3
Esto es genial, pero técnicamente no se trata de la disponibilidad de una 'red' sino más bien de '¿tengo conectividad a Internet a través de http?' Puede tener conexiones de red perfectas pero sin conectividad a Internet, por ejemplo, en una LAN independiente. Consulte para obtener más información sobre NCSI: technet.microsoft.com/en-us/library/cc766017.aspx
MichielB
1

Llame a este método para verificar la conexión de red.

public static bool IsConnectedToInternet()
        {
            bool returnValue = false;
            try
            {

                int Desc;
                returnValue = Utility.InternetGetConnectedState(out Desc, 0);
            }
            catch
            {
                returnValue = false;
            }
            return returnValue;
        }

Pon esto debajo de la línea de código.

[DllImport("wininet.dll")]
        public extern static bool InternetGetConnectedState(out int Description, int ReservedValue);
Kumar
fuente