Qual è il modo migliore per verificare la connettività Internet usando .NET?


237

Qual è il modo più rapido ed efficiente per verificare la connettività Internet in .NET?


6
Se l'utente ha una connessione Internet. Se l'utente può connettersi a Internet. Per inviare un registro e-mail.
Mohit Deshpande,

11
Basta inviare l'e-mail. Se l'utente non è connesso, probabilmente riceverai una sorta di eccezione (che probabilmente dovresti gestire comunque).
Seth,

15
Inoltre, si noti che non è possibile verificare se l'utente è connesso a Internet; tutto quello che puoi dire è se fossero collegati in passato . Supponiamo di avere un metodo: "bool c = IsConnected (); if (c) {DoSomething ();}" - tra la chiamata a IsConnected e DoSomething, il router di rete wireless potrebbe essere stato scollegato. IsConnected dovrebbe davvero essere chiamato WasRecentlyConnected.
Eric Lippert,

Windows NLM APIdovrebbe essere il migliore per questo. stackoverflow.com/questions/5405895/...
Mahbubur Rahman

Risposte:


292

Qualcosa del genere dovrebbe funzionare.

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
Questo è probabilmente meglio del ping di Google, perché penso che non abbiamo alcuna garanzia che Google continui a rispondere ai ping. D'altra parte, non riesco a immaginare un mondo in cui www.google.com non restituisca un codice HTML :)
Daniel Vassallo

3
@Daniel: vero da un lato, ma dall'altro, il download del sito Web è un po 'sovraccarico
Leo

9
In entrambi i casi, non c'è motivo di ritirare il 4KB: basta usare client.OpenRead (url). Se non genera un'eccezione, è stato in grado di connettersi.
Josh M.

14
In realtà non è così efficiente. Usarlo fa iniziare il mio programma oltre 1 minuto se non c'è internet. Probabilmente a causa del tentativo di risolvere il DNS. Il ping 8.8.8.8 (google dns) lo ha modificato in 3 secondi.
MadBoy,

8
@DanielVassallo I cannot image a world where www.google.com does not return some HTMLin Cina ad esempio ...
Jérôme MEVEL

84

Non è assolutamente possibile verificare in modo affidabile se esiste o meno una connessione a Internet (presumo si intenda l'accesso a Internet).

Puoi, tuttavia, richiedere risorse che non sono praticamente mai offline, come il ping di google.com o qualcosa di simile. Penso che questo sarebbe efficiente.

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 "Non è assolutamente possibile verificare in modo affidabile se esiste una connessione a Internet"
Woz

6
Tutto ciò che fa è verificare che google sia attivo quando lo hai eseguito il ping. Se l'istante successivo al successo del ping, Internet si interrompe, allora? Non ha senso controllare prima di farlo.
dbasnett,

12
E in che modo ciò è in contraddizione con l'affermazione principale della mia risposta?
Leone,

10
L'uso di "google.com" richiederà più tempo perché deve essere risolto. Invece, eseguire il ping direttamente tramite IP sarà più veloce. Il ping su indirizzi IP DNS pubblici di Google ( 8.8.8.8o 8.8.4.4) funziona bene per me.
Mangesh,

8
Vorrei ribadire il fatto che Beware - many schools and offices block the ping protocol.se si utilizza questo metodo per un'applicazione che verrà utilizzata dai clienti, si sconsiglia questo metodo di controllo di internet
user1

42

Invece di controllare, esegui semplicemente l'azione (richiesta web, posta, ftp, ecc.) E sii pronto affinché la richiesta fallisca, cosa che devi fare comunque, anche se il tuo controllo è andato a buon fine.

Considera quanto segue:

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

Se la rete non funziona, l'azione fallirà altrettanto rapidamente di un ping, ecc.

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

9
Destra! Fallo e basta, ma preparati a tutti i risultati.
Colonnello Panic,

3
Considera quanto segue: Devi fare qualcosa se la rete non è attiva per x tempo (ad es. Tracelog, reset del router)
Abir

2
Non l'OP, ma il motivo per cui voglio farlo è EVITARE IL DEFAULT 100 SECONDO TIMEOUT se la connettività Internet non è disponibile. La richiesta HTTP viene eseguita su un thread in background, quindi il thread dell'interfaccia utente non viene bloccato, ma la mia app non può uscire fino a quando il thread in background non ritorna dalla richiesta HTTP e termina. Piuttosto che cercare di trovare un valore di timeout del "mezzo felice", vorrei evitare del tutto la richiesta se sapessi che la connessione a Internet era inattiva.
Scott Smith,

2
Il mio punto era che non possiamo tenere conto di quando il servizio remoto potrebbe diventare disponibile / non disponibile. Inoltre, che dire dei siti che non rispondono ai ping?
dbasnett,

Un altro caso di utilizzo è un correttore online che mi avviserà non appena il mio Internet verrà eseguito il backup
Ben Philipp

28

NetworkInterface.GetIsNetworkAvailableè molto inaffidabile. Basta avere un po 'di VMware o altra connessione LAN e restituirà un risultato errato. Anche sul Dns.GetHostEntrymetodo ero solo preoccupato se l'URL di test potesse essere bloccato nell'ambiente in cui la mia applicazione doveva essere distribuita.

Quindi un altro modo che ho scoperto è usare il InternetGetConnectedStatemetodo. Il mio codice è

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

Durante i test, ho scoperto che InternetGetConnectedState è tornato vero quando è stato installato il lettore VMWare (Internet disconnesso). Ho dovuto disabilitarlo in Pannello di controllo \ Rete e Internet \ Connessioni di rete (VMNet1 e VMNet8).
HockeyJ,

Ok Justin Oringer. Anche se l'ho verificato ma devo verificare di nuovo
Kamran Shahid,

2
L'approccio migliore per me, dopo controllo ancora la connettività del mio servizio, quindi inizio le routine ... Volevo solo evitare le eccezioni.
Wagner Bertolini Junior,

4
Questo codice controlla solo se il cavo di rete è collegato.
HackerMan

14

Un test per la connessione a Internet eseguendo il ping di Google:

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

7
Una descrizione accompagnata da questa risposta sarebbe vantaggiosa per più persone rispetto all'autore originale della domanda.
Boeckm,

13
Attenzione: molte scuole e uffici bloccano il protocollo ping. Sciocco, lo so.
Colonnello Panic,

Non riesco a trovare la classe ping. Per favore potete aiutarmi. Sto lavorando su UWP e le altre informazioni sulla rete non funzionano
iam.Carrot

12

Non sono d'accordo con le persone che affermano: "Qual è il punto nel verificare la connettività prima di eseguire un'attività, come immediatamente dopo il controllo la connessione potrebbe andare persa". Sicuramente c'è un certo grado di incertezza in molti compiti di programmazione che noi sviluppatori intraprendiamo, ma ridurre l'incertezza a un livello di accettazione fa parte della sfida.

Di recente mi sono imbattuto in questo problema creando un'applicazione che includeva una funzionalità di mappatura collegata a un server di tessere online. Questa funzionalità doveva essere disabilitata quando si notava una mancanza di connettività Internet.

Alcune delle risposte in questa pagina sono state molto buone, ma hanno comunque causato molti problemi di prestazioni come l'impiccagione, principalmente in caso di assenza di connettività.

Ecco la soluzione che ho finito per usare, con l'aiuto di alcune di queste risposte e dei miei colleghi:

         // 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

Ho visto tutte le opzioni sopra elencate e l'unica opzione praticabile per verificare che Internet sia disponibile o meno è l'opzione "Ping". L'importazione [DllImport("Wininet.dll")]e System.Net.NetworkInformation.NetworkInterface.GetAllNetworkInterfaces() qualsiasi altra variazione della NetworkInterface classe non funziona correttamente nel rilevamento della disponibilità della rete. Questi metodi controllano solo se il cavo di rete è inserito o meno.

L '"opzione ping"

if(La connessione è disponibile) ritorna true

if(La connessione non è disponibile e il cavo di rete è inserito) ritorna false

if(Il cavo di rete non è inserito) Throws an exception

L'interfaccia di rete

if(Internet è disponibile) Restituisce True

if(Internet non è disponibile e il cavo di rete è collegato) Restituisce True

if(Il cavo di rete non è collegato) ritorna false

Il [DllImport ("Wininet.dll")]

if(Internet è disponibile) Restituisce True

if(Internet non è disponibile e il cavo di rete è collegato) Restituisce True

if(Il cavo di rete non è collegato) ritorna false

Quindi, in caso di [DllImport("Wininet.dll")] e NetworkInterface Non c'è modo di sapere se è disponibile una connessione Internet.


Questo non è vero, ho importato Wininet.dll, ho collegato il cavo di rete e non ho ottenuto il risultato corretto per lo scenario Internet.
Waldemar Gałęzinowski,

8

Non risolve il problema della caduta della rete tra il controllo e l'esecuzione del codice ma è abbastanza affidabile

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

Ottima idea, ma come hai detto potresti non essere perfetta. È possibile memorizzare nella cache anche i byte inviati / ricevuti per controlli futuri. Tuttavia non è ancora perfetto.
Todd,

Questo codice non funziona, per favore correggi. Controlla solo se il cavo di rete è collegato o meno.
HackerMan,

5

Il ping google.com introduce una dipendenza dalla risoluzione DNS. Il ping 8.8.8.8 va bene, ma Google è a pochi passi da me. Tutto quello che devo fare è eseguire il ping della cosa più vicina a me che è su Internet.

Posso usare la funzione TTL di Ping per eseguire il ping dell'hop n. 1, quindi dell'hop n. 2, ecc., Finché non ricevo una risposta da qualcosa che si trova su un indirizzo instradabile; se quel nodo si trova su un indirizzo instradabile, allora è su Internet. Per la maggior parte di noi, hop # 1 sarà il nostro gateway / router locale e hop # 2 sarà il primo punto sull'altro lato della nostra connessione in fibra o altro.

Questo codice funziona per me e risponde più rapidamente di alcuni degli altri suggerimenti in questo thread perché sta eseguendo il ping di ciò che è più vicino a me su 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

Ecco come viene implementato in Android.

Come prova di concetto, ho tradotto questo codice in 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

Un'altra opzione è l'API Network List Manager che è disponibile per Vista e Windows 7. L'articolo MSDN qui . Nell'articolo è presente un collegamento per scaricare esempi di codice che consentono di eseguire questa operazione:

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

Assicurarsi di aggiungere un riferimento alla libreria dei tipi di Elenco di rete 1.0 dalla scheda COM ... che verrà visualizzata come NETWORKLIST.


7
eeeeww. Usando l'inferno COM in .NET?
jgauffin,

@jgauffin Puoi forse spiegare perché si dovrebbe evitare COM in .NET? Rispetto alle altre soluzioni che ho trovato, la soluzione COM sembra funzionare abbastanza bene.
inexcitus,

2

Cerca di evitare il test delle connessioni rilevando l'eccezione. perché ci aspettiamo davvero che a volte potremmo perdere la connessione di rete.

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

1
Da dove viene NetworkInterface? EDIT: Lo trovo: System.Net.NetworkInformation
inspire_coding il


1

Personalmente trovo la risposta migliore di Anton e Moffeltje , ma ho aggiunto un segno di spunta per escludere le reti virtuali create da VMWare e altri.

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

Cordiali saluti dai documenti GetIsNetworkAvailable (): una connessione di rete è considerata disponibile se un'interfaccia di rete è contrassegnata come "up" e non è un'interfaccia loopback o tunnel. Non so se virtuale sarà sempre nel nome o nella descrizione dell'interfaccia. Quello è 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
Puoi aggiungere informazioni relative alla velocità di questo e come questo è meglio di altre soluzioni pubblicate. Questo aiuterà la tua risposta a rispondere pienamente alla domanda.
Ren,

8
Il problema con questa opzione è che bbsarebbe ancora vero anche quando la rete non è connessa a Internet.
halfpastfour.am

2
Sebbene sia vero che questo non risponde direttamente alla domanda, penso che sia ancora utile utilizzare GetIsNetworkAvailable come pre-controllo prima di provare a eseguire il ping di Google ecc.
Ben Hughes,

3
Questo codice non indica se la connessione Internet è disponibile o meno. Se si collega un cavo di rete senza Internet, questo sarà vero.
HackerMan,

1

Versione multi thread del 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

Non credo sia impossibile, ma non semplice.

Ho creato qualcosa del genere, e sì, non è perfetto, ma il primo passo è essenziale: verificare se c'è connettività di rete. L'API di Windows non fa un ottimo lavoro, quindi perché non fare un lavoro migliore?

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

È piuttosto semplice, ma aiuta davvero a migliorare la qualità del controllo, soprattutto quando si desidera controllare varie configurazioni proxy.

Così:

  • Controlla se c'è connettività di rete (rendilo davvero buono, forse hai anche dei log inviati agli sviluppatori quando ci sono falsi positivi per migliorare la funzione NetworkIsAvailable)
  • Ping HTTP
  • (Scorrere le configurazioni proxy con ping HTTP su ciascuna)

1
@hackerman questo è il primo passo non scontato. I programmatori possono elaborare un ping rapido sul proprio server se restituisce true, come secondo passaggio. È importante sottolineare che ciò fornisce un'alternativa al metodo API di Windows difettoso. Il resto è dettagli.
Todd,

3
Falsificare. Se nessuna interfaccia di rete è attiva, sicuramente non c'è Internet. L'interfaccia utente può essere aggiornata senza indugio, senza ulteriori controlli su altri host.
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;
    }
}

Per favore, commenta la tua risposta. Le risposte con solo codice non sono consentite.
ganchito55

È piuttosto autoesplicativo, sorvegliare per motivi di polizia?
tira il

0

Utilizzare NetworkMonitor per monitorare lo stato della rete e la connessione Internet.

Campione:

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

Bella idea, ma controlla la disponibilità della rete, non la disponibilità di Internet
John Demetriou

Questa classe controlla anche la disponibilità di Internet: SourceCode

il fatto è che l'ho provato, ma ha funzionato solo se non era disponibile alcuna rete
John Demetriou,

0

introduzione

In alcuni scenari è necessario verificare se Internet è disponibile o meno utilizzando il codice C # nelle applicazioni Windows. Può essere quello di scaricare o caricare un file utilizzando Internet in Windows Form o di ottenere alcuni dati dal database che si trova in una posizione remota, in queste situazioni il controllo di Internet è obbligatorio.

Ci sono alcuni modi per verificare la disponibilità di Internet usando C # dal codice dietro. Tutti questi modi sono spiegati qui, compresi i loro limiti.

  1. InternetGetConnectedState (WinInet)

L'API "wininet" può essere utilizzata per verificare se il sistema locale ha una connessione Internet attiva o meno. Lo spazio dei nomi utilizzato per questo è 'System.Runtime.InteropServices' e importa la dll 'wininet.dll' usando DllImport. Successivamente, crea una variabile booleana con extern static con un nome di funzione InternetGetConnectedState con due parametri descrizione e riservatoValue come mostrato nell'esempio.

Nota: il modificatore esterno viene utilizzato per dichiarare un metodo implementato esternamente. Un uso comune del modificatore extern è con l'attributo DllImport quando si utilizzano i servizi di interoperabilità per chiamare il codice non gestito. In questo caso, anche il metodo deve essere dichiarato statico.

Quindi creare un metodo con nome "IsInternetAvailable" come booleano. La funzione di cui sopra verrà utilizzata in questo metodo che restituisce lo stato Internet del sistema locale

[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'esempio seguente utilizza il metodo GetIsNetworkAvailable per determinare se è disponibile una connessione di rete.

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

Note (secondo MSDN): una connessione di rete è considerata disponibile se un'interfaccia di rete è contrassegnata come "up" e non è un'interfaccia loopback o tunnel.

Ci sono molti casi in cui un dispositivo o un computer non è connesso a una rete utile ma è ancora considerato disponibile e GetIsNetworkAvailable restituirà true. Ad esempio, se il dispositivo che esegue l'applicazione è connesso a una rete wireless che richiede un proxy, ma il proxy non è impostato, GetIsNetworkAvailable restituirà true. Un altro esempio di quando GetIsNetworkAvailable restituirà true è se l'applicazione è in esecuzione su un computer collegato a un hub o router in cui l'hub o il router ha perso la connessione upstream.

  1. Effettua il ping di un nome host sulla rete

Le classi Ping e PingReply consentono a un'applicazione di determinare se un computer remoto è accessibile in rete ottenendo risposta dall'host. Queste classi sono disponibili nello spazio dei nomi System.Net.NetworkInformation. L'esempio seguente mostra come eseguire il ping di 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;
}

Note (secondo MSDN): le applicazioni utilizzano la classe Ping per rilevare se è possibile raggiungere un computer remoto. La topologia di rete può determinare se Ping può contattare correttamente un host remoto. La presenza e la configurazione di proxy, apparecchiature NAT (Network Address Translation) o firewall possono impedire il successo del ping. Un ping riuscito indica solo che è possibile raggiungere l'host remoto sulla rete; la presenza di servizi di livello superiore (come un server Web) sull'host remoto non è garantita.

Commenti / Suggerimenti sono invitati. Buona programmazione ......!


-1

Per la mia applicazione testiamo anche il download di piccoli file.

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

Anche. Alcuni ISP possono utilizzare il server intermedio per memorizzare nella cache i file. Aggiungi un parametro casuale inutilizzato, ad es. https://www.microsoft.com/favicon.ico?req=random_number Può impedire la memorizzazione nella cache.


-1

Sto riscontrando problemi con questo metodo sul mio router / modem 3g, perché se Internet è disconnesso il router reindirizza la pagina alla sua pagina di risposta, quindi ricevi ancora un vapore e il tuo codice pensa che ci sia Internet. Le mele (o altre) hanno una pagina di deduzione hot-spot che restituisce sempre una certa risposta. L'esempio seguente restituisce la risposta "Success". Quindi sarai esattamente sicuro di poter connettere Internet e ottenere una risposta reale!

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

Ho tre test per una connessione a Internet.

  • Riferimento System.NeteSystem.Net.Sockets
  • Aggiungi le seguenti funzioni di test:

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

Esecuzione dei test

Se si effettua una Dictionarydi Stringe Booleanchiamato CheckList, è possibile aggiungere i risultati di ogni test per CheckList.

Ora, ripassa ciascuno di essi KeyValuePairusando un for...eachciclo.

Se CheckListcontiene un Valuedi true, allora sai che c'è una connessione a Internet.


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

Che funzioni


46
Se hai l'IP di google nella cache DNS, non invierà una richiesta DNS, quindi potrebbe tornare vero anche se non sei connesso
Thomas Levesque
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.