Quelle est la meilleure façon de vérifier la connectivité Internet à l'aide de .NET?


237

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


6
Si l'utilisateur a une connexion Internet. Si l'utilisateur peut se connecter à Internet. Afin d'envoyer un journal d'email.
Mohit Deshpande

11
Envoyez simplement l'e-mail. Si l'utilisateur n'est pas connecté, vous recevrez probablement une sorte d'exception (que vous devrez probablement gérer de toute façon).
Seth

15
Notez également qu'il n'y a aucun moyen de vérifier si l'utilisateur est connecté à Internet; tout ce que vous pouvez dire, c'est s'ils étaient connectés dans le passé . Supposons que vous disposiez d'une méthode: "bool c = IsConnected (); if (c) {DoSomething ();}" - entre l'appel à IsConnected et DoSomething, le routeur du réseau sans fil a peut-être été débranché. IsConnected devrait vraiment s'appeler WasRecentlyConnected.
Eric Lippert

Windows NLM APIdevrait être le meilleur pour cela. stackoverflow.com/questions/5405895/…
Mahbubur Rahman

Réponses:


292

Quelque chose comme ça devrait fonctionner.

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

18
C'est probablement mieux que d'envoyer un ping à Google, car je pense que nous n'avons aucune garantie que Google continue de répondre aux pings. D'un autre côté, je ne peux pas imaginer un monde où www.google.com ne renvoie pas de code HTML :)
Daniel Vassallo

3
@Daniel: vrai d'une part, mais d'autre part, le téléchargement du site Web est un peu imo
Leo

9
Quoi qu'il en soit, aucune raison de retirer les 4 Ko - utilisez simplement client.OpenRead (url) à la place. S'il ne lève pas d'exception, il a pu se connecter.
Josh M.

14
Ce n'est en fait pas si efficace. En utilisant cela, mon programme démarre plus d'une minute s'il n'y a pas d'Internet. Probablement en raison de la tentative de résolution du DNS. Pinging 8.8.8.8 (google dns) l'a changé en 3 secondes.
MadBoy

8
@DanielVassallo I cannot image a world where www.google.com does not return some HTMLen Chine par exemple ...
Jérôme MEVEL

84

Il n'y a absolument aucun moyen de vérifier de manière fiable s'il y a une connexion Internet ou non (je suppose que vous voulez dire l'accès à Internet).

Vous pouvez cependant demander des ressources qui ne sont pratiquement jamais hors ligne, comme envoyer un ping à google.com ou quelque chose de similaire. Je pense que ce 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;
}

24
+1 "Il n'y a absolument aucun moyen de vérifier de manière fiable s'il y a une connexion Internet"
woz

6
Tout cela ne fait que vérifier que Google est en place lorsque vous l'avez pingé. Si l'instant suivant après votre ping réussi, Internet tombe en panne, alors quoi? Il est inutile de vérifier avant de faire.
dbasnett

12
Et comment cela contredit-il l'énoncé principal de ma réponse?
Leo

10
L'utilisation de "google.com" prendra plus de temps car elle doit être résolue. Au lieu de cela, le ping directement avec IP sera plus rapide. Le ping vers les adresses IP DNS publiques de Google ( 8.8.8.8ou 8.8.4.4) fonctionne bien pour moi.
Mangesh

8
Je tiens à réitérer le fait que Beware - many schools and offices block the ping protocol.si vous utilisez cette méthode pour une application qui sera utilisée par les clients, je déconseille cette méthode de vérification d'Internet
user1

42

Au lieu de vérifier, effectuez simplement l'action (demande Web, courrier, 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 réussi.

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

9
Droite! Faites-le, mais préparez-vous à tous les résultats.
Colonel Panic

3
Considérez ce qui suit: Vous devez faire quelque chose si le réseau est en panne pendant x heure (par exemple tracelog, réinitialisation du routeur)
Abir

2
Pas l'OP, mais la raison pour laquelle je veux le faire est D'ÉVITER LE DÉLAI PAR DÉFAUT DE 100 SECONDES si la connectivité Internet n'est pas disponible. La requête HTTP est effectuée sur un thread d'arrière-plan, de sorte que le thread d'interface utilisateur n'est pas bloqué, mais mon application ne peut pas quitter jusqu'à ce que le thread d'arrière-plan revienne de la demande HTTP et se termine. Plutôt que d'essayer de trouver une valeur de délai d'expiration "juste milieu", j'aimerais simplement éviter complètement la demande si je savais que la connexion Internet était en panne.
Scott Smith

2
Mon point était que nous ne pouvons pas expliquer quand le service à distance pourrait devenir disponible / indisponible. Et qu'en est-il des sites qui ne répondent pas aux pings?
dbasnett

Un autre cas d'utilisation est un vérificateur en ligne qui m'alertera dès que mon Internet sera de retour
Ben Philipp

28

NetworkInterface.GetIsNetworkAvailableest très peu fiable. Ayez juste une connexion VMware ou autre LAN et cela retournera un mauvais résultat. Aussi à propos de la Dns.GetHostEntryméthode, je voulais juste savoir si l'URL de test pouvait être bloquée dans l'environnement où mon application allait se déployer.

Donc, une autre façon dont j'ai découvert est d'utiliser la InternetGetConnectedStateméthode. 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);         
}

Lors des tests, j'ai constaté qu'InternetGetConnectedState retournait vrai lorsque le lecteur VMWare était installé (Internet déconnecté). J'ai dû le désactiver dans Panneau de configuration \ Réseau et Internet \ Connexions réseau (VMNet1 et VMNet8).
HockeyJ

Ok Justin Oringer.Bien que je l'ai vérifié mais je dois vérifier à nouveau
Kamran Shahid

2
Meilleure approche pour moi, je vérifie toujours ma connectivité de service après cela, puis démarre les routines ... Je voulais juste éviter les exceptions.
Wagner Bertolini Junior

4
Ce code vérifie uniquement si le câble réseau est branché.
HackerMan

14

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

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

7
Une description accompagnant cette réponse serait bénéfique pour plus de personnes que juste l'auteur original de la question.
Boeckm

13
Attention - de nombreuses écoles et bureaux bloquent le protocole ping. Idiot, je sais.
Colonel Panic

Je ne trouve pas la classe ping. pourrais-tu m'aider s'il te plaît. Je travaille sur UWP et les autres façons de parcourir les informations du réseau ne fonctionnent pas
iam.Carrot

12

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'effectuer une tâche, car immédiatement après le contrôle, la connexion peut être perdue". Certes, il existe un certain degré d'incertitude dans de nombreuses tâches de programmation que nous, en tant que développeurs, entreprenons, mais réduire l'incertitude à un niveau d'acceptation fait partie du défi.

J'ai récemment rencontré ce problème lors de la création d'une application incluant une fonction de mappage reliée à un serveur de tuiles en ligne. Cette fonctionnalité devait être désactivée en cas de manque de connectivité Internet.

Certaines des réponses sur cette page étaient très bonnes, mais ont cependant causé beaucoup de problèmes de performances tels que le blocage, principalement en cas d'absence de connectivité.

Voici la solution que j'ai fini par utiliser, avec 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

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". L'importation [DllImport("Wininet.dll")]et System.Net.NetworkInformation.NetworkInterface.GetAllNetworkInterfaces() ou toute autre variation de la NetworkInterface classe ne fonctionne pas bien pour détecter la disponibilité du réseau. Ces méthodes vérifient uniquement si le câble réseau est branché ou non.

L'option "Ping"

if(La connexion est disponible) retourne 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) Retours True

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

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

Le [DllImport ("Wininet.dll")]

if(Internet est disponible) Retours True

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

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

Donc, en cas de [DllImport("Wininet.dll")] et NetworkInterface Il n'y a aucun moyen de savoir si une connexion Internet est disponible.


Ce n'est pas vrai, j'ai importé Wininet.dll, le câble réseau branché et j'ai obtenu le résultat correct pour le scénario Internet n'étant pas disponible.
Waldemar Gałęzinowski

8

Ne résout pas le problème de panne de 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;
}

Excellente idée, mais comme vous l'avez dit, ce n'est peut-être pas parfait. Vous pouvez également mettre en cache les octets envoyés / reçus pour de futures vérifications. Mais pas encore parfait.
Todd

Ce code ne fonctionne pas, veuillez corriger. Il vérifie uniquement si le câble réseau est branché ou non.
HackerMan

5

Pinging google.com introduit une dépendance de résolution DNS. Pinging 8.8.8.8 est très bien, mais Google est à plusieurs sauts de moi. Tout ce que je dois faire est de cingler la chose la plus proche de moi qui est sur Internet.

Je peux utiliser la fonction TTL de Ping pour envoyer un ping au hop # 1, puis au hop # 2, etc., jusqu'à ce que j'obtienne une réponse de quelque chose qui se trouve sur une adresse routable; si ce nœud se trouve 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;
        }
    }
}

4

Voici comment il est implémenté dans Android.

Comme preuve de 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
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;
    }
}

2

Une autre option est l'API Network List Manager qui est disponible pour Vista et Windows 7. Article MSDN ici . Dans l'article se trouve un lien pour télécharger des exemples de code qui vous permettent de faire ceci:

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 la liste de réseaux 1.0 dans l'onglet COM ... qui apparaîtra comme NETWORKLIST.


7
eeeeww. Vous utilisez COM hell dans .NET?
jgauffin

@jgauffin Pouvez-vous peut-être expliquer pourquoi on devrait éviter COM dans .NET? Par rapport aux autres solutions que j'ai trouvées, la solution COM semble fonctionner assez bien.
inexcitus

2

Essayez d'éviter de tester les connexions en interceptant l'exception. car nous nous attendons vraiment à ce que parfois nous perdions la connexion réseau.

 if (NetworkInterface.GetIsNetworkAvailable() &&
     new Ping().Send(new IPAddress(new byte[] { 8, 8, 8, 8 }),2000).Status == IPStatus.Success)
 //is online
 else
 //is offline

1
D'où vient NetworkInterface? EDIT: Je le trouve: System.Net.NetworkInformation
inspire_coding


1

Personnellement , je trouve le mieux la réponse d' Anton et de moffeltje , mais j'ai ajouté une vérification pour exclure les réseaux virtuels mis en place 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));
}

Pour info à partir des documents GetIsNetworkAvailable (): Une connexion réseau est considérée comme disponible si une interface réseau est marquée "up" et n'est pas une interface de bouclage ou de tunnel. Je ne sais pas si virtuel sera toujours dans le nom ou la description de l'interface. Est-ce standard?
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");

1
Pouvez-vous ajouter des informations relatives à la vitesse de cela et à la façon dont cela est meilleur que les autres solutions publiées. Cela vous aidera à répondre pleinement à la question.
Ren

8
Le problème avec cette option est que cela bbserait toujours vrai même lorsque le réseau n'est pas connecté à Internet.
halfpastfour.am

2
Bien qu'il soit vrai que cela ne répond pas directement à la question, je pense qu'il est toujours utile d'utiliser GetIsNetworkAvailable comme pré-vérification avant d'essayer d'envoyer une requête ping à Google, etc.
Ben Hughes

3
Ce code ne dit pas si la connexion Internet est disponible ou non. Si vous branchez un câble réseau sans Internet, cela reviendra vrai.
HackerMan

1

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

Je ne pense 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 y a une connectivité réseau. L'API Windows ne fait pas un excellent 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é de la vérification, surtout lorsque vous souhaitez vérifier diverses configurations de proxy.

Alors:

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

1
@hackerman c'est la première étape non évidente. Les codeurs peuvent élaborer un ping rapide sur leur propre serveur s'il renvoie vrai, dans un deuxième temps. Surtout, cela fournit une alternative à la méthode API Windows défectueuse. Le reste, ce sont les détails.
Todd

3
Falsifier. Si aucune interface réseau n'est active, il n'y a certainement pas d'Internet. L'interface utilisateur peut être mise à jour immédiatement sans délai, sans autre vérification sur d'autres hôtes.
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;
    }
}

Veuillez commenter votre réponse. Les réponses contenant uniquement du code ne sont pas autorisées.
ganchito55

C'est assez explicite, le maintien de l'ordre pour le bien de la police?
roule le

0

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

Bonne idée, mais vérifie la disponibilité du réseau, pas la disponibilité d'Internet
John Demetriou

Cette classe vérifie également la disponibilité d'Internet: SourceCode

le problème est que je l'ai essayé, mais il ne s'est déclenché que si aucun réseau n'était disponible
John Demetriou

0

introduction

Dans certains scénarios, vous devez vérifier si Internet est disponible ou non en utilisant le code C # dans les applications Windows. Il peut s'agir de télécharger ou de télécharger un fichier via Internet sous Windows ou d'obtenir des données d'une base de données distante, dans ces situations, la vérification d'Internet est obligatoire.

Il existe plusieurs façons de vérifier la disponibilité d'Internet en utilisant C # à partir du code derrière. Toutes ces méthodes sont expliquées ici, y compris leurs limites.

  1. InternetGetConnectedState (wininet)

L'API 'wininet' peut être utilisée pour vérifier si le système local a une connexion Internet active ou non. L'espace de noms utilisé pour cela est «System.Runtime.InteropServices» et importez la dll «wininet.dll» à l'aide de DllImport. Après cela, créez une variable booléenne avec statique externe avec un nom de fonction InternetGetConnectedState avec une description de deux paramètres et réservéValue comme indiqué dans l'exemple.

Remarque: Le modificateur extern est utilisé pour déclarer une méthode implémentée en externe. Une utilisation courante du modificateur extern est avec l'attribut DllImport lorsque vous utilisez des services Interop pour appeler du code non managé. Dans ce cas, la méthode doit également être déclarée comme statique.

Créez ensuite une méthode avec le nom 'IsInternetAvailable' comme booléen. La fonction ci-dessus sera utilisée dans cette méthode qui renvoie le statut Internet du système 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

L'exemple suivant utilise la méthode GetIsNetworkAvailable pour déterminer si une connexion réseau est 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");
}

Remarques (selon MSDN): Une connexion réseau est considérée comme disponible si une interface réseau est marquée "up" et n'est pas une interface de bouclage ou de tunnel.

Il existe de nombreux cas dans lesquels un périphérique ou un ordinateur n'est pas connecté à un réseau utile mais est toujours considéré comme disponible et GetIsNetworkAvailable renvoie true. Par exemple, si le périphérique exécutant l'application est connecté à un réseau sans fil qui nécessite un proxy, mais que le proxy n'est pas défini, GetIsNetworkAvailable renvoie true. Un autre exemple de moment où GetIsNetworkAvailable retournera true est si l'application s'exécute sur un ordinateur connecté à un concentrateur ou un routeur où le concentrateur ou le routeur a perdu la connexion en amont.

  1. Ping un nom d'hôte sur le réseau

Les classes Ping et PingR répondre permettent à une application de déterminer si un ordinateur distant est accessible sur le réseau en obtenant une réponse de l'hôte. Ces classes sont disponibles dans l'espace de noms System.Net.NetworkInformation. L'exemple suivant montre comment envoyer une requête ping à un hôte.

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

Remarques (selon MSDN): les applications utilisent la classe Ping pour détecter si un ordinateur distant est accessible. La topologie du réseau peut déterminer si Ping peut contacter avec succès un hôte distant. La présence et la configuration de proxys, d'équipements de traduction d'adresses réseau (NAT) ou de pare-feu peuvent empêcher Ping de réussir. Un ping réussi indique uniquement que l'hôte distant peut être atteint sur le réseau; la présence de services de niveau supérieur (comme un serveur Web) sur l'hôte distant n'est pas garantie.

Les commentaires / suggestions sont invités. Bon codage ......!


-1

Pour mon application, nous testons également en téléchargeant un petit fichier.

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

Aussi. Certains FAI peuvent utiliser un serveur intermédiaire pour mettre en cache le fichier. Ajouter un paramètre aléatoire inutilisé, par exemple. https://www.microsoft.com/favicon.ico?req=random_number Peut empêcher la mise en cache.


-1

J'ai un problème avec cette méthode sur mon routeur / modem 3G, car si Internet est déconnecté, le routeur redirige la page vers sa page de réponse, donc vous obtenez toujours une vapeur et votre code pense qu'il y a Internet. Les pommes (ou autres) ont une page de détection de points chauds qui renvoie toujours une certaine réponse. L'exemple suivant renvoie la réponse «Succès». Vous serez donc exactement sûr de pouvoir vous connecter à Internet et obtenir une réponse réelle!

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

-2

J'ai trois tests pour une connexion Internet.

  • Référence System.Net etSystem.Net.Sockets
  • Ajoutez les fonctions de test suivantes:

Test 1

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

Test 2

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

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

Réalisation des tests

Si vous faites un Dictionaryde Stringet Booleanappelé CheckList, vous pouvez ajouter les résultats de chaque test CheckList.

Maintenant, récapitulez à travers chacun en KeyValuePairutilisant une for...eachboucle.

Si CheckListcontient un Valuede true, alors vous savez qu'il existe une connexion Internet.


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

Ça marche


46
Si vous avez l'IP de Google dans votre cache DNS, il n'enverra pas de demande DNS, donc il pourrait retourner vrai même si vous n'êtes pas connecté
Thomas Levesque
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.