2010-03-26 26 views
27

Tengo un código C# que básicamente carga un archivo a través del protocolo FTP (usando FtpWebRequest). Me gustaría, sin embargo, primero determinar si hay una conexión a Internet que funcione antes de intentar cargar el archivo (ya que, si no hay razón para intentarlo, el software debería simplemente quedarse dormido por un tiempo y verificarlo nuevamente) .¿Cómo detectar la conexión a Internet que funciona en C#?

¿Hay una manera fácil de hacerlo o simplemente debería intentar cargar el archivo y en caso de que fallara, intente de nuevo, suponiendo que la conexión de red no funcionara?

+1

Hola a todos! Antes que nada, ¡gracias por todas sus respuestas! Iré con la respuesta de JaredPar por elegancia. @Damien: Sé que podrían pasar muchas cosas, solo quiero hacer un simple: ¿Hay una conexión neta? ¿No? Vuelve en 30 minutos. ¿Sí? Ok, vamos a intentar subir enfoque. Con el código de JaredPar, no debería ser tan difícil. Nada mucho más sofisticado. Gracias por responder, sin embargo. @kzen: Pinging no es realmente una buena respuesta. Yo, por mi parte, tengo bloqueadas las solicitudes ICMP en mi empresa, por lo que revisarlas de esa manera fallaría incluso con una conexión funcional. ¡Gracias de cualquier manera! – Detariael

+0

Andy Shellam: Su respuesta es básicamente la misma que la de JaredPar, no la he elegido solo porque me parece que JaredPar se ve más elegante. ¡Gracias por tu respuesta de todos modos! – Detariael

+0

Cambió el carácter acusado al de Zyo, ya que incluye loopback/túneles. – Detariael

Respuesta

31

sólo tiene que utilizar la función normal

System.Net.NetworkInformation.NetworkInterface.GetIsNetworkAvailable() 

que deviene verdadero de falso si la conexión está activa.

From MSDN: Una conexión de red se considera como disponible si cualquier interfaz de red está marcado como "arriba" y no es una interfaz de bucle o túnel.

Tenga en cuenta que la conectividad no es todo, puede conectarse a una red local y el enrutador no está conectado a Internet, por ejemplo. Para saber realmente si está conectado a Internet, pruebe la clase Ping.

+0

Al desconectar el cable, el método anterior devuelve VERDADERO. – mmmmmm

+0

¿Esto también funciona cuando una conexión inalámbrica es limitada? –

+0

@mmmmmm Desconectar el cable no significa que TODAS las redes no están disponibles. Usted podría estar en un wifi, por ejemplo. – Zyo

12

Creo que la mejor aproximación puede utilizar es comprobar el valor OperationalStatus del tipo NetworkInterface.

using System.Net.NetworkInformation; 

public bool IsNetworkLikelyAvailable() { 
    return NetworkInterface 
    .GetAllNetworkInterfaces() 
    .Any(x => x.OperationalStatus == OperationalStatus.Up); 
} 

Recuerde que esto es una aproximación. En el momento en que este método retorne, la computadora podría perder o ganar su conexión a Internet. IMO. Me gustaría ir directamente a la carga y manejar el error ya que no se puede probar que no va a suceder.

+1

Esto puede devolver la interfaz loopback y cualquier interfaz de túnel que haya configurado. Probablemente deberías informar 'no' incluso si alguno de estos informes 'Arriba'. Sé que loopback informa 'Up' casi todo el tiempo, independientemente del estado de Internet. – colithium

+0

Gracias por ese JaredPar, usted acaba de diseñar mi aplicación mucho más fácil. – grefly

6

Piense en la situación en la que su cheque vuelve y dice "la conexión está allí", y antes de que pueda iniciar su FTP, la conexión se interrumpe.

O donde la conexión cae parcialmente a través de su solicitud de FTP.

Dado que hay que codificar para estas situaciones todos modos, simplemente omitir la comprobación

Editar en respuesta a los comentarios de Jason

Usted también puede tener la condición opuesta se producen - que cuando se comprueba para una conexión, ninguno existe, pero un momento después, surge su conexión. Entonces, ¿qué haces? ¿Empiezas a molestar al usuario por la ausencia de una conexión, a pesar de que ahora está disponible?

Al final del día, se trata de una gran cantidad de recursos (su conexión de red, cualquier enrutador intermedio, el host, su servicio de FTP). Todos estos están sujetos a cambios fuera de su control (como lo indicó el comentario de Seth), y ninguna cantidad de prueba previa responderá a la pregunta "¿podré completar esta carga"?

Como el OP indicó que está pensando en un enfoque de "retroceder e intentar más tarde", entonces creo que es apropiado hacer todo eso en segundo plano y no molestar al usuario, a menos que lo haya intentado. por una cantidad de tiempo "irrazonable" sin éxito.

+0

+1 Una conexión de red en funcionamiento no implica que el host remoto esté activo y que tenga un servidor FTP en funcionamiento. – Seth

+5

Buena respuesta, pero creo que la estás mirando al frente: si no tienes una conexión, tu programa no debería intentar iniciar ninguna comunicación; podrías encontrarlo bloqueando los tiempos de espera y/o desperdiciando la CPU tiempo en intentos infructuosos de hablar sobre un enlace muerto y/o informar cientos de errores estúpidos al usuario. Los buenos programas detectarán con gracia que el enlace está fuera de línea y dejarán de intentar usarlo. –

6

¿No puede usar el Ping Class del System.Net.NetworkInformation Namespace para hacer ping al servidor FTP antes de intentar cargar el archivo?

+2

Excepto que esto fallará si el host remoto bloquea las solicitudes de ping, lo cual es una buena práctica y algunos proveedores de hosting grandes lo hacen. –

+0

Sí, pensé que era obvio, así que no me molesté en mencionarlo ... Como otros ya han notado, no hay forma de estar absolutamente seguros de que la conexión estará disponible en el momento exacto de la solicitud de FTP con cualquier tipo de comprobación, pero creo que un ping es una aproximación lo suficientemente buena y muy simple de implementar. –

14

Hay un evento de "disponibilidad de red cambiado" que se dispara cuando el estado "arriba" de una conexión de red cambia en una interfaz que no es un túnel o bucle.

Puede leer el estado de todos los adaptadores de red en el sistema al inicio, almacenar el valor actual de "red disponible", luego escuchar este evento y cambiar la variable de estado de la red cuando se desate este evento. También parece que manejará las conexiones de acceso telefónico e ISDN también.

Otorgado hay otros factores a tener en cuenta, como la NIC está conectada a un enrutador (y funciona) pero la conexión a Internet en el enrutador está inactiva, o el host remoto no responde, pero esto al menos evitar que intente hacer una conexión que no va a funcionar si no hay una conexión de red para empezar (por ejemplo, el enlace VPN o RDSI está inactivo)

Esta es una aplicación de consola C# - comience a ejecutarse, luego desactive o desconecte la conexión de red :-)

class Program 
{ 
    static bool networkIsAvailable = false; 

    static void Main(string[] args) 
    { 
     NetworkInterface[] nics = NetworkInterface.GetAllNetworkInterfaces(); 

     foreach (NetworkInterface nic in nics) 
     { 
      if (
       (nic.NetworkInterfaceType != NetworkInterfaceType.Loopback && nic.NetworkInterfaceType != NetworkInterfaceType.Tunnel) && 
       nic.OperationalStatus == OperationalStatus.Up) 
      { 
       networkIsAvailable = true; 
      } 
     } 

     Console.Write("Network availability: "); 
     Console.WriteLine(networkIsAvailable); 

     NetworkChange.NetworkAvailabilityChanged += new NetworkAvailabilityChangedEventHandler(NetworkChange_NetworkAvailabilityChanged); 

     Console.ReadLine(); 
    } 

    static void NetworkChange_NetworkAvailabilityChanged(object sender, NetworkAvailabilityEventArgs e) 
    { 
     networkIsAvailable = e.IsAvailable; 

     Console.Write("Network availability: "); 
     Console.WriteLine(networkIsAvailable); 
    } 
} 
+1

+1 para darse cuenta de que los bucles y túneles no representan una conexión. Desearía haber leído su respuesta antes de intentar implementar la respuesta aceptada ... – colithium

5

si el ping es difícil para usted, solo use webclient.

public static bool CheckForInternetConnection() 
{ 
    try 
    { 
     using (var client = new WebClient()) 
     using (var stream = client.OpenRead("http://www.google.com")) 
     { 
      return true; 
     } 
    } 
    catch 
    { 
     return false; 
    } 
} 

o en cualquier otro sitio. EDITAR: puede usar http://www.msftncsi.com/ este sitio. Este es un sitio que se ejecuta solo para conectividad a Internet. Véase la explicación detallada de la forma de registro de Windows 7 encuentra conectividad a Internet http://blog.superuser.com/2011/05/16/windows-7-network-awareness/

1

acabo de escribir funciones asíncronas para hacer eso:

private void myPingCompletedCallback(object sender, PingCompletedEventArgs e) 
    { 
     if (e.Cancelled) 
      return; 

     if (e.Error != null) 
      return; 

     if (e.Reply.Status == IPStatus.Success) 
     { 
      //ok connected to internet, do something... 
     } 
    } 

    private void checkInternet() 
    { 
     Ping myPing = new Ping(); 
     myPing.PingCompleted += new PingCompletedEventHandler(myPingCompletedCallback); 
     try 
     { 
      myPing.SendAsync("google.com", 3000 /*3 secs timeout*/, new byte[32], new PingOptions(64, true)); 
     } 
     catch 
     { 
     } 
    } 
Cuestiones relacionadas