Come posso verificare la presenza di una connessione di rete?


Risposte:


153

È possibile verificare una connessione di rete in .NET 2.0 utilizzando GetIsNetworkAvailable():

System.Net.NetworkInformation.NetworkInterface.GetIsNetworkAvailable()

Per monitorare le modifiche nell'indirizzo IP o le modifiche nella disponibilità della rete, utilizzare gli eventi della classe NetworkChange :

System.Net.NetworkInformation.NetworkChange.NetworkAvailabilityChanged
System.Net.NetworkInformation.NetworkChange.NetworkAddressChanged

9
Questo si prende cura della "disponibilità limitata"?
tofutim

Questo non funziona sempre in WPF. Alcuni laptop restituiscono false e alcune restituiscono true
krilovich

Funziona davvero? Ho appena scritto questa riga e spento il mio router e ancora restituisce true!
Mushfiq

1
NetworkInterface.GetIsNetworkAvailable()è stato molto inaffidabile nella mia applicazione (.NET 4.5, Windows 10), soprattutto se eseguito in una macchina virtuale. La gestione degli eventi da NetworkAvailabilityChangedè stata affidabile.
eskimwier

Questo non è affidabile. leggere stackoverflow.com/a/25779403/2377343
T.Todua

174

La risposta contrassegnata va bene al 100%, tuttavia, ci sono alcuni casi in cui il metodo standard viene ingannato dalle carte virtuali (scatola virtuale, ...). È anche spesso desiderabile scartare alcune interfacce di rete in base alla loro velocità (porte seriali, modem, ...).

Ecco un pezzo di codice che controlla questi casi:

    /// <summary>
    /// Indicates whether any network connection is available
    /// Filter connections below a specified speed, as well as virtual network cards.
    /// </summary>
    /// <returns>
    ///     <c>true</c> if a network connection is available; otherwise, <c>false</c>.
    /// </returns>
    public static bool IsNetworkAvailable()
    {
        return IsNetworkAvailable(0);
    }

    /// <summary>
    /// Indicates whether any network connection is available.
    /// Filter connections below a specified speed, as well as virtual network cards.
    /// </summary>
    /// <param name="minimumSpeed">The minimum speed required. Passing 0 will not filter connection using speed.</param>
    /// <returns>
    ///     <c>true</c> if a network connection is available; otherwise, <c>false</c>.
    /// </returns>
    public static bool IsNetworkAvailable(long minimumSpeed)
    {
        if (!NetworkInterface.GetIsNetworkAvailable())
            return false;

        foreach (NetworkInterface ni in NetworkInterface.GetAllNetworkInterfaces())
        {
            // discard because of standard reasons
            if ((ni.OperationalStatus != OperationalStatus.Up) ||
                (ni.NetworkInterfaceType == NetworkInterfaceType.Loopback) ||
                (ni.NetworkInterfaceType == NetworkInterfaceType.Tunnel))
                continue;

            // this allow to filter modems, serial, etc.
            // I use 10000000 as a minimum speed for most cases
            if (ni.Speed < minimumSpeed)
                continue;

            // discard virtual cards (virtual box, virtual pc, etc.)
            if ((ni.Description.IndexOf("virtual", StringComparison.OrdinalIgnoreCase) >= 0) ||
                (ni.Name.IndexOf("virtual", StringComparison.OrdinalIgnoreCase) >= 0))
                continue;

            // discard "Microsoft Loopback Adapter", it will not show as NetworkInterfaceType.Loopback but as Ethernet Card.
            if (ni.Description.Equals("Microsoft Loopback Adapter", StringComparison.OrdinalIgnoreCase))
                continue;

            return true;
        }
        return false;
    }

17
questo è corretto e merita molti voti positivi - Ho scoperto che l'evento NetworkAvailabilityChanged menzionato nella risposta accettata non viene attivato in modo affidabile, il che è probabilmente causato dagli adattatori virtuali come menzionato in questa risposta
Marek

1
+1 per il controllo aggiuntivo per le macchine virtuali. Incontra questo caso ieri. Ma penso ancora che questo non gestisca "Hype-V", perché non hanno "virtuale" nel loro nome.
Herdo

3
@Herdo - sì, il codice non è perfetto e non penso che possa esserci qualcosa di perfetto in un mondo virtuale. Ma puoi migliorarlo.
Simon Mourier

@SimonMourier Hai ragione. Volevo solo notare che, se qualcuno viene comunque restituito vero, se non c'è connessione -> Questo potrebbe essere un problema :)
Herdo

1
@noelicus - Sui progetti su cui ho lavorato finora, ho implementato un sistema di monitoraggio / polling periodico (semplici richieste HTTP GET perché stavo prendendo di mira un server web) che genera eventi quando il server viene rilevato come "inattivo" (non raggiungibile tramite HTTP) o "su" (nuovamente raggiungibile). Nel caso generale, puoi definire cosa significa "affidabile" nel tuo caso e implementare una logica simile.
Simon Mourier

9

Microsoft windows vista e 7 utilizzano la tecnica NCSI (Network Connectivity Status Indicator):

  1. NCSI esegue una ricerca DNS su www.msftncsi.com, quindi richiede http://www.msftncsi.com/ncsi.txt . Questo file è un file di testo normale e contiene solo il testo " Microsoft NCSI ".
  2. NCSI invia una richiesta di ricerca DNS per dns.msftncsi.com. Questo indirizzo DNS dovrebbe risolversi in 131.107.255.255. Se l'indirizzo non corrisponde, si presume che la connessione Internet non funzioni correttamente.

3
Questo è fantastico, ma tecnicamente non riguarda la disponibilità di una "rete", ma piuttosto "ho connettività Internet tramite http?" Puoi avere connessioni di rete perfette ma nessuna connettività a Internet, ad esempio su una lan stand-alone. Vedi per maggiori informazioni su NCSI: technet.microsoft.com/en-us/library/cc766017.aspx
MichielB

1

Chiama questo metodo per controllare la connessione di rete.

public static bool IsConnectedToInternet()
        {
            bool returnValue = false;
            try
            {

                int Desc;
                returnValue = Utility.InternetGetConnectedState(out Desc, 0);
            }
            catch
            {
                returnValue = false;
            }
            return returnValue;
        }

Mettilo sotto la riga di codice.

[DllImport("wininet.dll")]
        public extern static bool InternetGetConnectedState(out int Description, int ReservedValue);
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.