web-dev-qa-db-fra.com

Quel est le meilleur moyen de vérifier la connectivité Internet en utilisant .NET?

Quel est le moyen le plus rapide et le plus efficace de vérifier la connectivité Internet dans .NET?

192
Mohit Deshpande

Quelque chose comme ça devrait marcher.

System.Net.WebClient

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

Il n’ya absolument aucun moyen de vérifier de manière fiable s’il existe ou non une connexion Internet (je suppose que vous voulez dire par accès à Internet).

Vous pouvez toutefois demander des ressources qui ne sont pratiquement jamais hors ligne, telles que la commande ping de google.com ou quelque chose de similaire. Je pense que cela serait efficace.

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;
}
70
Leo

Au lieu de vérifier, effectuez simplement l'action (requête Web, mail, ftp, etc.) et préparez-vous à l'échec de la demande, ce que vous devez faire de toute façon, même si votre vérification a abouti.

Considérer ce qui suit:

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 le réseau est en panne, votre action échouera aussi rapidement qu'un ping, etc. 

1 - start to perform action
2 - if the net is down(or goes down) the action will fail
35
dbasnett

NetworkInterface.GetIsNetworkAvailable est très peu fiable. Avoir juste une connexion VMware ou une autre connexion LAN et le résultat sera erroné . Egalement à propos de la méthode Dns.GetHostEntry Je voulais simplement savoir si l'URL de test pourrait être bloquée dans l'environnement où mon application va être déployée.

J'ai donc découvert une autre méthode en utilisant la méthode InternetGetConnectedState . Mon code est 

[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);         
}
22
Kamran Shahid

Je ne suis pas d'accord avec les personnes qui déclarent: "Quel est l'intérêt de vérifier la connectivité avant d'exécuter une tâche, car immédiatement après la vérification, la connexion peut être perdue" ... entreprendre, mais réduire l’incertitude à un niveau d’acceptation fait partie du défi.

J'ai récemment rencontré ce problème en créant une application comportant une fonctionnalité de mappage liée à un serveur de tuiles en ligne. Cette fonctionnalité devait être désactivée lorsqu'un manque de connectivité Internet était constaté.

Certaines des réponses fournies sur cette page étaient très bonnes, mais ont néanmoins posé de nombreux problèmes de performances, tels que le blocage, principalement dans le cas de l'absence de connectivité.

Voici la solution que j'ai finalement utilisée, à l'aide de certaines de ces réponses et de mes collègues:

         // 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
            }));
        }
    }
11
PJRobot

Un test de connexion Internet en envoyant une requête ping à Google:

new Ping().Send("www.google.com.mx").Status == IPStatus.Success
10
Jaime Macias

Ne résout pas le problème de la coupure du réseau entre la vérification et l'exécution de votre code mais est assez fiable

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;
}
8
Anton

J'ai vu toutes les options énumérées ci-dessus et la seule option viable pour vérifier si Internet est disponible ou non est l'option "Ping" . Importer [DllImport("Wininet.dll")] et System.Net.NetworkInformation.NetworkInterface.GetAllNetworkInterfaces() Ou toute autre variante de la classe NetworkInterface ne fonctionne pas bien pour détecter la disponibilité du réseau. Ces méthodes vérifient uniquement si le câble de réseau est branché ou non.

L'option "Ping"

if (La connexion est disponible) renvoie true

if (La connexion n'est pas disponible et le câble réseau est branché) renvoie false

if (le câble réseau n'est pas branché) Throws an exception

L'interface réseau

if (Internet est disponible) Renvoie True

if (Internet n'est pas disponible et le câble réseau est branché) Retourne True

if (le câble réseau n'est pas branché) renvoie false

Le [DllImport ("Wininet.dll")]

if (Internet est disponible) Renvoie True

if (Internet n'est pas disponible et le câble réseau est branché) Retourne True

if (le câble réseau n'est pas branché) renvoie false

Donc, en cas de [DllImport("Wininet.dll")] et NetworkInterface, il n’ya aucun moyen de savoir si une connexion Internet est disponible.

7
HackerMan
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;
    }
}
3
Shai Segev

Voici comment cela est mis en œuvre dans Android.

Pour prouver le concept, j'ai traduit ce code en 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
    }
}
3
breez

Le ping sur google.com introduit une dépendance à la résolution DNS. Pinging 8.8.8.8, c'est bien, mais Google est à quelques sauts de distance de moi. Tout ce que je dois faire est de faire un ping sur la chose la plus proche de moi qui est sur Internet. 

Je peux utiliser la fonction TTL de Ping pour exécuter les étapes 1, puis 2, etc. si ce nœud est sur une adresse routable, il est sur Internet. Pour la plupart d'entre nous, le saut n ° 1 sera notre passerelle/routeur local, et le saut n ° 2 sera le premier point de l'autre côté de notre connexion fibre ou autre. 

Ce code fonctionne pour moi et répond plus rapidement que certaines des autres suggestions de ce fil, car il envoie une requête ping à ce qui est le plus proche de moi sur 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;
        }
    }
}
2
Jinlye

Je trouve personnellement la réponse de Anton et moffeltje best, mais j’ai ajouté une coche pour exclure les réseaux virtuels configurés par VMWare et d’autres.

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));
}
1
Spegeli

Une autre option est l’API Network List Manager, disponible pour Vista et Windows 7. Article MSDN ici . Dans cet article, vous trouverez un lien pour télécharger des exemples de code vous permettant de le faire:

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

Assurez-vous d’ajouter une référence à la bibliothèque de types de Network List 1.0 à partir de l’onglet COM ... qui apparaîtra sous la forme NETWORKLIST.

1
gierow

Utilisez NetworkMonitor pour surveiller l’état du réseau et la connexion Internet.

Échantillon:

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");
        }
    }
}
0
AmRo

Essaye ça:

 using System.Net.NetworkInformation;
 bool isNetAvailable = NetworkInterface.GetIsNetworkAvailable();
0
Shaahin
bool bb = System.Net.NetworkInformation.NetworkInterface.GetIsNetworkAvailable();

if (bb == true)
    MessageBox.Show("Internet connections are available");
else
    MessageBox.Show("Internet connections are not available");
0
Hari Prasath
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;
    }
}
0
Salih Alija

Si vous souhaitez informer l'utilisateur/prendre des mesures chaque fois qu'un changement de réseau/connexion se produit.
Utiliser l'API NLM:

0
Ansary Ans21

Version multi-thread 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";
          }
      }
  }
0
Nime Cloud

Je ne penserais pas que ce soit impossible, mais pas simple.

J'ai construit quelque chose comme ça, et oui ce n'est pas parfait, mais la première étape est essentielle: vérifier s'il existe une connectivité réseau. Windows Api ne fait pas du bon travail, alors pourquoi ne pas faire un meilleur travail?

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;
}

C'est assez simple, mais cela aide vraiment à améliorer la qualité du contrôle, en particulier lorsque vous souhaitez vérifier différentes configurations de proxy. 

Alors:

  • Vérifiez s'il y a une connectivité réseau (rendez-vous vraiment bien, peut-être même envoyez-vous des journaux aux développeurs lorsqu'il y a des faux positifs pour améliorer la fonction NetworkIsAvailable)
  • Ping HTTP
  • (Parcourez les configurations de proxy avec HTTP Pings sur chacune)
0
Todd