¿Cuál es la mejor manera de verificar la conectividad a Internet usando .NET?

237

¿Cuál es la forma más rápida y eficiente de verificar la conectividad a Internet en .NET?

Mohit Deshpande
fuente
66
Si el usuario tiene una conexión a internet. Si el usuario puede conectarse a internet. Para enviar un registro de correo electrónico.
Mohit Deshpande
11
Solo envía el correo electrónico. Si el usuario no está conectado, es probable que reciba algún tipo de excepción (que probablemente tendría que manejar de todos modos).
Seth
15
Además, tenga en cuenta que no hay forma de verificar si el usuario está conectado a Internet; todo lo que puedes decir es si estuvieron conectados en el pasado . Suponga que tiene un método: "bool c = IsConnected (); if (c) {DoSomething ();}" - entre la llamada a IsConnected y DoSomething, el enrutador de la red inalámbrica podría haberse desconectado. IsConnected realmente debería llamarse WasRecentlyConnected.
Eric Lippert el
Windows NLM APIdebería ser lo mejor para esto. stackoverflow.com/questions/5405895/…
Mahbubur Rahman

Respuestas:

292

Algo como esto debería funcionar.

System.Net.WebClient

public static bool CheckForInternetConnection()
{
    try
    {
        using (var client = new WebClient())
            using (client.OpenRead("http://google.com/generate_204")) 
                return true; 
    }
    catch
    {
        return false;
    }
}
ChaosPandion
fuente
18
Probablemente sea mejor que hacer ping a Google, porque creo que no tenemos garantía de que Google continúe respondiendo a los pings. Por otro lado, no puedo imaginar un mundo donde www.google.com no devuelva algo de HTML :)
Daniel Vassallo
3
@Daniel: cierto por un lado, pero por otro lado, en realidad descargar el sitio web es un poco imo
Leo
99
De cualquier manera, no hay razón para retirar el 4KB: solo use client.OpenRead (url) en su lugar. Si no arroja una excepción, se pudo conectar.
Josh M.
14
Eso en realidad no es tan eficiente. Usar eso hace que mi programa comience más de 1 minuto si no hay internet. Probablemente debido a tratar de resolver DNS. Pinging 8.8.8.8 (google dns) lo cambió a 3 segundos.
MadBoy
8
@DanielVassallo I cannot image a world where www.google.com does not return some HTMLen China, por ejemplo ...
Jérôme MEVEL
84

No hay absolutamente ninguna manera de que pueda verificar de manera confiable si hay una conexión a Internet o no (supongo que se refiere al acceso a Internet).

Sin embargo, puede solicitar recursos que prácticamente nunca están fuera de línea, como hacer ping a google.com o algo similar. Creo que esto sería eficiente.

try { 
    Ping myPing = new Ping();
    String host = "google.com";
    byte[] buffer = new byte[32];
    int timeout = 1000;
    PingOptions pingOptions = new PingOptions();
    PingReply reply = myPing.Send(host, timeout, buffer, pingOptions);
    return (reply.Status == IPStatus.Success);
}
catch (Exception) {
    return false;
}
León
fuente
24
+1 "No hay absolutamente ninguna manera de verificar de forma confiable si hay una conexión a Internet"
woz
66
Todo lo que hace es verificar que google esté activo cuando lo pinchaste. Si el siguiente instante después de su ping exitoso, Internet cae, ¿entonces qué? No tiene sentido comprobar antes de hacerlo.
dbasnett
12
¿Y cómo contradice esto con la declaración principal de mi respuesta?
Leo
10
Usar "google.com" llevará más tiempo porque debe resolverse. En cambio, hacer ping directamente usando IP será más rápido. Hacer ping a las direcciones IP públicas de DNS de Google ( 8.8.8.8o 8.8.4.4) funciona bien para mí.
Mangesh
8
Quisiera reiterar el punto de que Beware - many schools and offices block the ping protocol.si está utilizando este método para una aplicación que será utilizada por clientes, desaconsejaría este método de verificación de Internet
usuario1
42

En lugar de verificar, simplemente realice la acción (solicitud web, correo, ftp, etc.) y esté preparado para que la solicitud falle, lo que debe hacer de todos modos, incluso si su verificación fue exitosa.

Considera lo siguiente:

1 - check, and it is OK
2 - start to perform action 
3 - network goes down
4 - action fails
5 - lot of good your check did

Si la red está inactiva, su acción fallará tan rápido como un ping, etc.

1 - start to perform action
2 - if the net is down(or goes down) the action will fail
dbasnett
fuente
99
¡Correcto! Solo hazlo, pero prepárate para todos los resultados.
Coronel Panic
3
Tenga en cuenta lo siguiente: debe hacer algo si la red está inactiva durante x tiempo (p. Ej., Registro de seguimiento, reinicio del enrutador)
Abir
2
No es el OP, pero la razón por la que quiero hacer esto es EVITAR EL SEGUNDO TIEMPO DE ESPERA POR DEFECTO 100 si la conectividad a Internet no está disponible. La solicitud HTTP se realiza en un subproceso en segundo plano, por lo que el subproceso de la interfaz de usuario no se está bloqueando, pero mi aplicación no puede salir hasta que el subproceso en segundo plano regrese de la solicitud HTTP y finalice. En lugar de tratar de encontrar algún valor de tiempo de espera de "medio feliz", me gustaría evitar la solicitud si supiera que la conexión a Internet no funciona.
Scott Smith
2
Mi punto era que no podemos dar cuenta de cuándo el servicio remoto podría estar disponible / no disponible. Además, ¿qué pasa con los sitios que no responden a pings?
dbasnett
Otro caso de uso es un verificador en línea que me alertará tan pronto como vuelva a funcionar mi Internet
Ben Philipp
28

NetworkInterface.GetIsNetworkAvailableEs muy poco confiable. Solo tenga un poco de VMware u otra conexión LAN y obtendrá un resultado incorrecto. También sobre el Dns.GetHostEntrymétodo, me preocupaba si la URL de prueba podría estar bloqueada en el entorno donde se implementará mi aplicación.

Entonces, otra forma que descubrí es usando el InternetGetConnectedStatemétodo. Mi código es

[System.Runtime.InteropServices.DllImport("wininet.dll")]
private extern static bool InternetGetConnectedState(out int Description, int ReservedValue);

public static bool CheckNet()
{
     int desc;
     return InternetGetConnectedState(out desc, 0);         
}
Kamran Shahid
fuente
Durante las pruebas, descubrí que InternetGetConnectedState devuelve true cuando se instaló VMWare player (internet desconectado). Tuve que deshabilitarlo en Panel de control \ Red e Internet \ Conexiones de red (VMNet1 y VMNet8).
HockeyJ
Ok Justin Oringer. Aunque lo he comprobado pero tengo que verificarlo nuevamente
Kamran Shahid
2
El mejor enfoque para mí, aún compruebo la conectividad de mi servicio después de eso, luego comienzo las rutinas ... Solo quería evitar excepciones.
Wagner Bertolini Junior
44
Este código solo verifica si el cable de red está enchufado.
HackerMan
14

Una prueba de conexión a Internet haciendo ping a Google:

new Ping().Send("www.google.com.mx").Status == IPStatus.Success
Jaime Macias
fuente
77
Una descripción que acompañe esta respuesta sería beneficiosa para más personas que solo el autor original de la pregunta.
Boeckm el
13
Cuidado: muchas escuelas y oficinas bloquean el protocolo ping. Tonto, lo sé.
Coronel Panic
No puedo encontrar la clase de ping. Me podría ayudar. Estoy trabajando en UWP y las otras formas de pasar por la información de la red no están funcionando
iam.Carrot
12

No estoy de acuerdo con las personas que dicen: "¿Cuál es el punto de verificar la conectividad antes de realizar una tarea, ya que inmediatamente después de la verificación se puede perder la conexión". Seguramente hay un cierto grado de incertidumbre en muchas tareas de programación que nosotros, como desarrolladores, emprendemos, pero reducir la incertidumbre a un nivel de aceptación es parte del desafío.

Recientemente me encontré con este problema al crear una aplicación que incluye una función de mapeo que se vincula a un servidor de mosaico en línea. Esta funcionalidad se deshabilitaría cuando se observara una falta de conectividad a Internet.

Algunas de las respuestas en esta página fueron muy buenas, pero sin embargo causaron muchos problemas de rendimiento, como el bloqueo, principalmente en el caso de la falta de conectividad.

Aquí está la solución que terminé usando, con la ayuda de algunas de estas respuestas y mis colegas:

         // Insert this where check is required, in my case program start
         ThreadPool.QueueUserWorkItem(CheckInternetConnectivity);
    }

    void CheckInternetConnectivity(object state)
    {
        if (System.Net.NetworkInformation.NetworkInterface.GetIsNetworkAvailable())
        {
            using (WebClient webClient = new WebClient())
            {
                webClient.CachePolicy = new System.Net.Cache.RequestCachePolicy(System.Net.Cache.RequestCacheLevel.BypassCache);
                webClient.Proxy = null;
                webClient.OpenReadCompleted += webClient_OpenReadCompleted;
                webClient.OpenReadAsync(new Uri("<url of choice here>"));
            }
        }
    }

    volatile bool internetAvailable = false; // boolean used elsewhere in code

    void webClient_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e)
    {
        if (e.Error == null)
        {
            internetAvailable = true;
            Dispatcher.Invoke(DispatcherPriority.Normal, new Action(() =>
            {
                // UI changes made here
            }));
        }
    }
PJRobot
fuente
11

He visto todas las opciones enumeradas anteriormente y la única opción viable para verificar si Internet está disponible o no es la opción "Ping". Importación [DllImport("Wininet.dll")]y System.Net.NetworkInformation.NetworkInterface.GetAllNetworkInterfaces() O cualquier otra variación de la NetworkInterface clase no funcionar bien en la detección de la disponibilidad de los métodos network.These solamente comprobar si el cable de red está conectado o no.

La "opción Ping"

if(La conexión está disponible) devuelve true

if(La conexión no está disponible y el cable de red está enchufado) vuelve false

if(El cable de red no está enchufado) Throws an exception

La interfaz de red

if(Internet está disponible) Devoluciones True

if(Internet no está disponible y el cable de red está enchufado) Devoluciones True

if(El cable de red no está enchufado) regresa false

El [DllImport ("Wininet.dll")]

if(Internet está disponible) Devoluciones True

if(Internet no está disponible y el cable de red está enchufado) Devoluciones True

if(El cable de red no está enchufado) regresa false

Entonces, en caso de [DllImport("Wininet.dll")] y NetworkInterface no hay forma de saber si hay conexión a Internet disponible.

HackerMan
fuente
Esto no es cierto, importé Wininet.dll, conecté el cable de red y obtuve el resultado correcto para que el escenario Internet no esté disponible.
Waldemar Gałęzinowski
8

No resuelve el problema de la caída de la red entre la comprobación y la ejecución de su código, pero es bastante confiable

public static bool IsAvailableNetworkActive()
{
    // only recognizes changes related to Internet adapters
    if (System.Net.NetworkInformation.NetworkInterface.GetIsNetworkAvailable())
    {
        // however, this will include all adapters -- filter by opstatus and activity
        NetworkInterface[] interfaces = System.Net.NetworkInformation.NetworkInterface.GetAllNetworkInterfaces();
        return (from face in interfaces
                where face.OperationalStatus == OperationalStatus.Up
                where (face.NetworkInterfaceType != NetworkInterfaceType.Tunnel) && (face.NetworkInterfaceType != NetworkInterfaceType.Loopback)
                select face.GetIPv4Statistics()).Any(statistics => (statistics.BytesReceived > 0) && (statistics.BytesSent > 0));
    }

    return false;
}
Anton
fuente
Gran idea, pero como dijiste podría no ser perfecto. También puede almacenar en caché los bytes enviados / recibidos para futuras comprobaciones. Aunque todavía no es perfecto.
Todd
Este código no funciona, corríjalo. Solo verifica si el cable de red está enchufado o no.
HackerMan
5

Hacer ping a google.com introduce una dependencia de resolución de DNS. Hacer ping 8.8.8.8 está bien, pero Google está a varios saltos de mí. Todo lo que necesito hacer es hacer ping a la cosa más cercana a mí que está en Internet.

Puedo usar la función TTL de Ping para hacer ping al salto n. ° 1, luego al salto n. ° 2, etc., hasta que reciba una respuesta de algo que está en una dirección enrutable; si ese nodo está en una dirección enrutable, entonces está en internet. Para la mayoría de nosotros, el salto n. ° 1 será nuestra puerta de enlace / enrutador local, y el salto n. ° 2 será el primer punto al otro lado de nuestra conexión de fibra o lo que sea.

Este código funciona para mí y responde más rápido que algunas de las otras sugerencias en este hilo porque está haciendo ping a lo que esté más cerca de mí en Internet.

using System.Net;
using System.Net.Sockets;
using System.Net.NetworkInformation;
using System.Diagnostics;

internal static bool ConnectedToInternet()
{
    const int maxHops = 30;
    const string someFarAwayIpAddress = "8.8.8.8";

    // Keep pinging further along the line from here to google 
    // until we find a response that is from a routable address
    for (int ttl = 1; ttl <= maxHops; ttl++)
    {
        Ping pinger = new Ping();
        PingOptions options = new PingOptions(ttl, true);
        byte[] buffer = new byte[32];
        PingReply reply = null;
        try
        {
            reply = pinger.Send(someFarAwayIpAddress, 10000, buffer, options);
        }
        catch (System.Net.NetworkInformation.PingException pingex)
        {
            Debug.Print("Ping exception (probably due to no network connection or recent change in network conditions), hence not connected to internet. Message: " + pingex.Message);
            return false;
        }

        System.Diagnostics.Debug.Print("Hop #" + ttl.ToString() + " is " + (reply.Address == null ? "null" : reply.Address.ToString()) + ", " + reply.Status.ToString());

        if (reply.Status != IPStatus.TtlExpired && reply.Status != IPStatus.Success)
        {
            Debug.Print("Hop #" + ttl.ToString() + " is " + reply.Status.ToString() + ", hence we are not connected.");
            return false;
        }

        if (IsRoutableAddress(reply.Address))
        {
            System.Diagnostics.Debug.Print("That's routable so you must be connected to the internet.");
            return true;
        }
    }

    return false;
}

private static bool IsRoutableAddress(IPAddress addr)
{
    if (addr == null)
    {
        return false;
    }
    else if (addr.AddressFamily == AddressFamily.InterNetworkV6)
    {
        return !addr.IsIPv6LinkLocal && !addr.IsIPv6SiteLocal;
    }
    else // IPv4
    {
        byte[] bytes = addr.GetAddressBytes();
        if (bytes[0] == 10)
        {   // Class A network
            return false;
        }
        else if (bytes[0] == 172 && bytes[1] >= 16 && bytes[1] <= 31)
        {   // Class B network
            return false;
        }
        else if (bytes[0] == 192 && bytes[1] == 168)
        {   // Class C network
            return false;
        }
        else
        {   // None of the above, so must be routable
            return true;
        }
    }
}
Jinlye
fuente
4

Así es como se implementa en Android.

Como prueba de concepto, traduje este código a C #:

var request = (HttpWebRequest)WebRequest.Create("http://g.cn/generate_204");
request.UserAgent = "Android";
request.KeepAlive = false;
request.Timeout = 1500;

using (var response = (HttpWebResponse)request.GetResponse())
{
    if (response.ContentLength == 0 && response.StatusCode == HttpStatusCode.NoContent)
    {
        //Connection to internet available
    }
    else
    {
        //Connection to internet not available
    }
}
Breez
fuente
3
private bool ping()
{
    System.Net.NetworkInformation.Ping pingSender = new System.Net.NetworkInformation.Ping();
    System.Net.NetworkInformation.PingReply reply = pingSender.Send(address);
    if (reply.Status == System.Net.NetworkInformation.IPStatus.Success)
    {                
        return true;
    }
    else
    {                
        return false;
    }
}
Shai Segev
fuente
2

Otra opción es la API de Network List Manager que está disponible para Vista y Windows 7. Artículo de MSDN aquí . En el artículo hay un enlace para descargar ejemplos de código que le permiten hacer esto:

AppNetworkListUser nlmUser = new AppNetworkListUser();
Console.WriteLine("Is the machine connected to internet? " + nlmUser.NLM.IsConnectedToInternet.ToString());

Asegúrese de agregar una referencia a la Biblioteca de tipos de la Lista de redes 1.0 desde la pestaña COM ... que aparecerá como NETWORKLIST.

alegría
fuente
77
eeeeww. ¿Usa COM hell en .NET?
jgauffin
@jgauffin ¿Puede explicar por qué uno debería evitar COM en .NET? En comparación con las otras soluciones que encontré, la solución COM parece funcionar bastante bien.
inexcitus
2

Intente evitar probar las conexiones detectando la excepción. porque realmente esperamos que a veces perdamos la conexión de red.

 if (NetworkInterface.GetIsNetworkAvailable() &&
     new Ping().Send(new IPAddress(new byte[] { 8, 8, 8, 8 }),2000).Status == IPStatus.Success)
 //is online
 else
 //is offline
Shervin Ivari
fuente
1
¿De dónde viene la interfaz de red? EDITAR: Lo encuentro: System.Net.NetworkInformation
inspire_coding
1

Personalmente encuentro la respuesta de Anton y moffeltje mejor, pero agregué un cheque para excluir las redes virtuales configuradas por VMWare y otros.

public static bool IsAvailableNetworkActive()
{
    // only recognizes changes related to Internet adapters
    if (!System.Net.NetworkInformation.NetworkInterface.GetIsNetworkAvailable()) return false;

    // however, this will include all adapters -- filter by opstatus and activity
    NetworkInterface[] interfaces = System.Net.NetworkInformation.NetworkInterface.GetAllNetworkInterfaces();
    return (from face in interfaces
            where face.OperationalStatus == OperationalStatus.Up
            where (face.NetworkInterfaceType != NetworkInterfaceType.Tunnel) && (face.NetworkInterfaceType != NetworkInterfaceType.Loopback)
            where (!(face.Name.ToLower().Contains("virtual") || face.Description.ToLower().Contains("virtual")))
            select face.GetIPv4Statistics()).Any(statistics => (statistics.BytesReceived > 0) && (statistics.BytesSent > 0));
}
Spegeli
fuente
FYI de los documentos GetIsNetworkAvailable (): se considera que una conexión de red está disponible si alguna interfaz de red está marcada como "activa" y no es una interfaz de bucle o de túnel. No sé si virtual siempre estará en el nombre o la descripción de la interfaz. ¿Es eso estándar?
Mike Cheel
1
bool bb = System.Net.NetworkInformation.NetworkInterface.GetIsNetworkAvailable();

if (bb == true)
    MessageBox.Show("Internet connections are available");
else
    MessageBox.Show("Internet connections are not available");
Hari Prasath
fuente
1
¿Puede agregar información relacionada con la velocidad de esto y cómo esto es mejor que otras soluciones publicadas? Esto ayudará a su respuesta a abordar completamente la pregunta.
Ren
8
El problema con esta opción es que bbaún sería cierto incluso cuando la red no esté conectada a Internet.
halfpastfour.am
2
Si bien es cierto que esto no responde directamente a la pregunta, creo que aún es útil usar GetIsNetworkAvailable como una verificación previa antes de intentar hacer ping a Google, etc.
Ben Hughes
3
Este Código no dice si la conexión a Internet está disponible o no. Si conecta un cable de red sin internet, volverá a ser cierto.
HackerMan
1

Versión multiproceso de ping:

  using System;
  using System.Collections.Generic;
  using System.Diagnostics;
  using System.Net.NetworkInformation;
  using System.Threading;


  namespace OnlineCheck
  {
      class Program
      {

          static bool isOnline = false;

          static void Main(string[] args)
          {
              List<string> ipList = new List<string> {
                  "1.1.1.1", // Bad ip
                  "2.2.2.2",
                  "4.2.2.2",
                  "8.8.8.8",
                  "9.9.9.9",
                  "208.67.222.222",
                  "139.130.4.5"
                  };

              int timeOut = 1000 * 5; // Seconds


              List<Thread> threadList = new List<Thread>();

              foreach (string ip in ipList)
              {

                  Thread threadTest = new Thread(() => IsOnline(ip));
                  threadList.Add(threadTest);
                  threadTest.Start();
              }

              Stopwatch stopwatch = Stopwatch.StartNew();

              while (!isOnline && stopwatch.ElapsedMilliseconds <= timeOut)
              {
                   Thread.Sleep(10); // Cooldown the CPU
              }

              foreach (Thread thread in threadList)
              { 
                  thread.Abort(); // We love threads, don't we?
              }


              Console.WriteLine("Am I online: " + isOnline.ToYesNo());
              Console.ReadKey();
          }

          static bool Ping(string host, int timeout = 3000, int buffer = 32)
          {
              bool result = false;

              try
              {
                  Ping ping = new Ping();                
                  byte[] byteBuffer = new byte[buffer];                
                  PingOptions options = new PingOptions();
                  PingReply reply = ping.Send(host, timeout, byteBuffer, options);
                  result = (reply.Status == IPStatus.Success);
              }
              catch (Exception ex)
              {

              }

              return result;
          }

          static void IsOnline(string host)
          {
              isOnline =  Ping(host) || isOnline;
          }
      }

      public static class BooleanExtensions
      {
          public static string ToYesNo(this bool value)
          {
              return value ? "Yes" : "No";
          }
      }
  }
Nime Cloud
fuente
0

No creo que sea imposible, simplemente no es sencillo.

He construido algo como esto, y sí, no es perfecto, pero el primer paso es esencial: verificar si hay alguna conectividad de red. Windows Api no hace un gran trabajo, entonces ¿por qué no hacer un mejor trabajo?

bool NetworkIsAvailable()
{
    var all = System.Net.NetworkInformation.NetworkInterface.GetAllNetworkInterfaces();
    foreach (var item in all)
    {
        if (item.NetworkInterfaceType == NetworkInterfaceType.Loopback)
            continue;
        if (item.Name.ToLower().Contains("virtual") || item.Description.ToLower().Contains("virtual"))
            continue; //Exclude virtual networks set up by VMWare and others
        if (item.OperationalStatus == OperationalStatus.Up)
        {
            return true;
        }
    }

    return false;
}

Es bastante simple, pero realmente ayuda a mejorar la calidad de la verificación, especialmente cuando desea verificar varias configuraciones de proxy.

Entonces:

  • Compruebe si hay conectividad de red (haga que esto sea realmente bueno, tal vez incluso envíe registros a los desarrolladores cuando haya falsos positivos para mejorar la función NetworkIsAvailable)
  • HTTP Ping
  • (Recorra las configuraciones de Proxy con HTTP Pings en cada una)
Todd
fuente
1
@hackerman, este es el primer paso no obvio. Los codificadores pueden resolver un ping rápido a su propio servidor si devuelve verdadero, como un segundo paso. Es importante destacar que esto proporciona una alternativa al método de API de Windows defectuoso. El resto son detalles.
Todd
3
Para falsificar. Si no hay una interfaz de red activa, definitivamente no hay internet. La interfaz de usuario se puede actualizar de inmediato sin demora, sin más controles en otros hosts.
Todd
0
public static bool Isconnected = false;

public static bool CheckForInternetConnection()
{
    try
    {
        Ping myPing = new Ping();
        String host = "google.com";
        byte[] buffer = new byte[32];
        int timeout = 1000;
        PingOptions pingOptions = new PingOptions();
        PingReply reply = myPing.Send(host, timeout, buffer, pingOptions);
        if (reply.Status == IPStatus.Success)
        {
            return true;
        }
        else if (reply.Status == IPStatus.TimedOut)
        {
            return Isconnected;
        }
        else
        {
            return false;
        }
    }
    catch (Exception)
    {
        return false;
    }
}

public static void CheckConnection()
{
    if (CheckForInternetConnection())
    {
        Isconnected = true;
    }
    else
    {
        Isconnected = false;
    }
}
Salih Alija
fuente
Por favor comente su respuesta. No se permiten respuestas con solo código.
ganchito55
Es bastante autoexplicativo, ¿policías por el bien de la policía?
lanza el
0

Use NetworkMonitor para monitorear el estado de la red y la conexión a Internet.

Muestra:

namespace AmRoNetworkMonitor.Demo
{
    using System;

    internal class Program
    {
        private static void Main()
        {
            NetworkMonitor.StateChanged += NetworkMonitor_StateChanged;
            NetworkMonitor.StartMonitor();

            Console.WriteLine("Press any key to stop monitoring.");
            Console.ReadKey();
            NetworkMonitor.StopMonitor();

            Console.WriteLine("Press any key to close program.");
            Console.ReadKey();
        }

        private static void NetworkMonitor_StateChanged(object sender, StateChangeEventArgs e)
        {
            Console.WriteLine(e.IsAvailable ? "Is Available" : "Is Not Available");
        }
    }
}

fuente
Buena idea, pero comprueba la disponibilidad de la red, no la disponibilidad de Internet
John Demetriou
Esta clase también verifica la disponibilidad de Internet: Código fuente
la cosa es que lo intenté, pero solo se disparó si no había red disponible
John Demetriou
0

Introducción

En algunos escenarios, debe verificar si Internet está disponible o no utilizando el código C # en las aplicaciones de Windows. Puede ser para descargar o cargar un archivo a través de Internet en formularios de Windows o para obtener algunos datos de la base de datos que se encuentra en una ubicación remota, en estas situaciones, la verificación de Internet es obligatoria.

Hay algunas formas de verificar la disponibilidad de Internet usando C # desde el código detrás. Todas estas formas se explican aquí, incluidas sus limitaciones.

  1. InternetGetConnectedState (wininet)

La API 'wininet' se puede usar para verificar si el sistema local tiene conexión a Internet activa o no. El espacio de nombres utilizado para esto es 'System.Runtime.InteropServices' e importa el dll 'wininet.dll' usando DllImport. Después de esto, cree una variable booleana con estática externa con un nombre de función InternetGetConnectedState con la descripción de dos parámetros y reservedValue como se muestra en el ejemplo.

Nota: El modificador externo se usa para declarar un método que se implementa externamente. Un uso común del modificador externo es con el atributo DllImport cuando usa los servicios de Interop para llamar a un código no administrado. En este caso, el método también debe declararse como estático.

A continuación, cree un método con el nombre 'IsInternetAvailable' como booleano. La función anterior se utilizará en este método que devuelve el estado de Internet del sistema local.

[DllImport("wininet.dll")]
private extern static bool InternetGetConnectedState(out int description, int reservedValue);
public static bool IsInternetAvailable()
{
    try
    {
        int description;
        return InternetGetConnectedState(out description, 0);
    }
    catch (Exception ex)
    {
        return false;
    }
}
  1. GetIsNetworkAvailable

El siguiente ejemplo utiliza el método GetIsNetworkAvailable para determinar si hay una conexión de red disponible.

if (System.Net.NetworkInformation.NetworkInterface.GetIsNetworkAvailable())
{
    System.Windows.MessageBox.Show("This computer is connected to the internet");
}
else
{
    System.Windows.MessageBox.Show("This computer is not connected to the internet");
}

Observaciones (según MSDN): se considera que una conexión de red está disponible si alguna interfaz de red está marcada como "activada" y no es una interfaz de bucle o de túnel.

Hay muchos casos en los que un dispositivo o computadora no está conectado a una red útil, pero todavía se considera disponible y GetIsNetworkAvailable volverá verdadero. Por ejemplo, si el dispositivo que ejecuta la aplicación está conectado a una red inalámbrica que requiere un proxy, pero el proxy no está configurado, GetIsNetworkAvailable devolverá true. Otro ejemplo de cuándo GetIsNetworkAvailable devolverá verdadero es si la aplicación se está ejecutando en una computadora que está conectada a un concentrador o enrutador donde el concentrador o enrutador ha perdido la conexión ascendente.

  1. Hacer ping a un nombre de host en la red

Las clases Ping y PingReply permiten que una aplicación determine si se puede acceder a una computadora remota a través de la red mediante la respuesta del host. Estas clases están disponibles en el espacio de nombres System.Net.NetworkInformation. El siguiente ejemplo muestra cómo hacer ping a un host.

protected bool CheckConnectivity(string ipAddress)
{
    bool connectionExists = false;
    try
    {
        System.Net.NetworkInformation.Ping pingSender = new System.Net.NetworkInformation.Ping();
        System.Net.NetworkInformation.PingOptions options = new System.Net.NetworkInformation.PingOptions();
        options.DontFragment = true;
        if (!string.IsNullOrEmpty(ipAddress))
        {
            System.Net.NetworkInformation.PingReply reply = pingSender.Send(ipAddress);
            connectionExists = reply.Status == 
System.Net.NetworkInformation.IPStatus.Success ? true : false;
        }
    }
    catch (PingException ex)
    {
        Logger.LogException(ex.Message, ex);
    }
    return connectionExists;
}

Observaciones (según MSDN): las aplicaciones utilizan la clase Ping para detectar si se puede acceder a una computadora remota. La topología de la red puede determinar si Ping puede contactar con éxito a un host remoto. La presencia y configuración de servidores proxy, equipos de traducción de direcciones de red (NAT) o firewalls pueden evitar que Ping tenga éxito. Un Ping exitoso indica solo que se puede llegar al host remoto en la red; no se garantiza la presencia de servicios de nivel superior (como un servidor web) en el host remoto.

Comentarios / Sugerencias están invitados. Feliz codificación ......!

Khuram Shahzad
fuente
-1

Para mi aplicación también probamos descargando un pequeño archivo.

string remoteUri = "https://www.microsoft.com/favicon.ico"

WebClient myWebClient = new WebClient();

try
{
    byte[] myDataBuffer = myWebClient.DownloadData (remoteUri);
    if(myDataBuffer.length > 0) // Or add more validate. eg. checksum
    {
        return true;
    }
}
catch
{
    return false;
}

También. Algunos ISP pueden usar un servidor intermedio para almacenar en caché el archivo. Añadir parámetro aleatorio no utilizado, por ejemplo. https://www.microsoft.com/favicon.ico?req=random_number Puede evitar el almacenamiento en caché.

usuario282341
fuente
-1

Tengo un problema con ese método en mi enrutador / módem 3g, porque si Internet está desconectado, el enrutador redirige la página a su página de respuesta, por lo que aún obtiene un vapor y su código cree que hay internet. Las manzanas (u otras) tienen una página de detección de puntos críticos que siempre devuelve una respuesta determinada. La siguiente muestra devuelve la respuesta "Éxito". ¡Entonces estará exactamente seguro de que puede conectarse a Internet y obtener una respuesta real!

public static bool CheckForInternetConnection()
{
    try
    {       
        using (var webClient = new WebClient())
        using (var stream = webClient.OpenRead("http://captive.apple.com/hotspot-detect.html"))
        {
            if (stream != null)
            {
                //return true;
                stream.ReadTimeout = 1000;
                using (var reader = new StreamReader(stream, Encoding.UTF8, false))
                {
                    string line;
                    while ((line = reader.ReadLine()) != null)
                    {
                        if (line == "<HTML><HEAD><TITLE>Success</TITLE></HEAD><BODY>Success</BODY></HTML>")
                        {
                            return true;
                        }
                        Console.WriteLine(line);
                    }
                }

            }
            return false;
        }
    }
    catch
    {

    }
    return false;
}
Yusuf GURDAG
fuente
-2

Tengo tres pruebas para una conexión a Internet.

  • Referencia System.NetySystem.Net.Sockets
  • Agregue las siguientes funciones de prueba:

Prueba 1

public bool IsOnlineTest1()
{
    try
    {
        IPHostEntry dummy = Dns.GetHostEntry("https://www.google.com");
        return true;
    }
    catch (SocketException ex)
    {
        return false;
    }
}

Prueba 2

public bool IsOnlineTest2()
{
    try
    {
        IPHostEntry dummy = Dns.GetHostEntry("https://www.google.com");
        return true;
    }
    catch (SocketException ex)
    {
        return false;
    }
}

Prueba 3

public bool IsOnlineTest3()
{
    System.Net.WebRequest req = System.Net.WebRequest.Create("https://www.google.com");
    System.Net.WebResponse resp = default(System.Net.WebResponse);
    try
    {
        resp = req.GetResponse();
        resp.Close();
        req = null;
        return true;
    }
    catch (Exception ex)
    {
        req = null;
        return false;
    }
}

Realizando las pruebas

Si realiza un Dictionaryde Stringy Booleanllamó CheckList, puede agregar los resultados de cada prueba CheckList.

Ahora, repita a través de cada uno KeyValuePairusando un for...eachbucle.

Si CheckListcontiene un Valuede true, entonces sabe que hay una conexión a Internet.

M. Liviu
fuente
-4
public static bool HasConnection()
{
    try
    {
        System.Net.IPHostEntry i = System.Net.Dns.GetHostEntry("www.google.com");
        return true;
    }
    catch
    {
        return false;
    }
}

Eso funciona

slayerIQ
fuente
46
Si tiene la IP de Google en su caché de DNS, no enviará una solicitud de DNS, por lo que podría ser verdadera incluso si no está conectado
Thomas Levesque,