2009-12-07 28 views
12

So che non sono il primo a porre la domanda: come faccio a sapere se la mia domanda è online o no? Ho trovato questo post: StackOverflow. Voglio farlo con C# e .NET 3.5.Determinare se la connessione Internet è disponibile

Si consiglia di eseguire il ping della risorsa regolarmente. Non sono molto contento di questo consiglio. Preferirei rilevare un cambio di rete e POI eseguire il ping del mio servizio per verificare se è online.

.NET fornisce due eventi per questo scopo: NetworkChange.NetworkAvailabilityChanged NetworkChange.NetworkAddressChanged

Il primo evento suona bene, ma è attivato solo se l'ultima scheda di rete che è in linea va offline. Ho diverse schede di rete virtuali che sono state installate da VMWare e quelle sono sempre online. Il secondo evento funziona, ma tra collegare il cavo di rete e l'evento, ci sono spesso 5 secondi di attesa. L'icona della barra delle applicazioni di Windows reagisce più o meno immediatamente quando sto scollegando il cavo. Qual è il modo migliore per essere veloce come questa icona del vassoio?

mia soluzione sarebbe quello di interrogare NetworkInterface.GetAllNetworkInterfaces() ogni 500ms e di gettare il mio proprio evento nel caso in cui lo stato di una scheda di rete è cambiato.

Ci deve essere una soluzione migliore :)

+0

Come pensate di rilevare tutte le modifiche rilevanti della rete? Non c'è davvero alcun modo per la tua applicazione di notare se qualche collegamento vitale è perso lungo la strada. –

+0

Vedere la mia modifica per alcune nuove informazioni relative a Iphlpapi.dll e NotifyAddrChange – Webleeuw

+0

Online in che senso? Con un server? Se sei online con un server, perché non inviare semplicemente un messaggio di stato ogni 5 secondi per determinare se sei online o no? –

risposta

0

Pinging la risorsa regolarmente è l'unica opzione che vi darà una notifica se il servizio non è in linea, così come se il cliente non è in linea. Potenzialmente vuoi gestire entrambe le situazioni.

+0

Sì, lo so. Per me, il rischio che la rete di un utente specifico non sia disponibile è molto più alto del rischio che il server non sia disponibile. Effettueremo un ping, ma non regolarmente, ma solo quando l'applicazione si avvia e quando si verifica un cambio di rete. Forse faremo un ping regolarmente ma poi non ogni 500ms :) –

0

L'icona della barra di Windows è molto probabilmente collegata ai driver della scheda di rete, cioè al di sotto del livello del sistema operativo, motivo per cui può reagire così velocemente.

Poiché la scheda di rete è solo uno dei molti collegamenti tra il client e il servizio a cui accede su Internet, l'unico modo affidabile per rilevare se Internet è disponibile è quello di eseguire il polling di alcuni servizi su Internet, più o meno allo stesso modo del ping. Nel networking TCP/IP, questo è noto come keepalive e molti protocolli lo includeranno come opzione.

0

Informazioni sul ping: a seconda di come si desidera interpretare i risultati, il ping non mi sembra impermeabile. Cosa succede se l'obiettivo scade una volta ogni tanto, mentre la connessione rimane attiva? Devo ancora vedere il server che non manca mai di rispondere a un ping.

Controllare ogni X millis se l'interfaccia di rete è ancora in linea (proprietà NetworkInterface.OperationalStatus) sembra più affidabile se me lo chiedi.

EDIT: This articolo si occupa di eventi di rete a un livello inferiore rispetto alla classe System.Net.NetworkInformation.NetworkChange, o almeno così sembra. Sul mio pc funziona molto velocemente, quindi spero che tu possa usare quella soluzione.

+0

Grazie per il collegamento. Ho dato un'occhiata a questo. Sembra che sia usato NetworkChange. Questo è utile ma non ne sono felice dato che è troppo lento. –

+0

"Devo ancora vedere il server che non fallisce mai nel rispondere a un ping" - Questa è una cattiva ipotesi. Molte reti rilasciano pacchetti ICMP. –

+0

@Roboto: non capisco il tuo commento, forse a causa di una piccola discrepanza di comunicazione :). Con questa frase intendevo sottolineare il fatto che il ping non è affidabile perché un server può rilasciare uno o più pacchetti ping anche se è online. Più chiaramente: devo ancora vedere il server che risponde sempre e sempre a ogni ping inviato. – Webleeuw

2

Prova questa utilizzando networkChange classe

using System.Net.NetworkInformation 

private void Form5_Load(object sender, EventArgs e) 
{ 
    NetworkChange.NetworkAvailabilityChanged += new NetworkAvailabilityChangedEventHandler(NetworkChange_NetworkAvailabilityChanged); 
} 

private void NetworkChange_NetworkAvailabilityChanged(object sender, NetworkAvailabilityEventArgs e) 
{ 
    if (e.IsAvailable) 
    { 
     MessageBox.Show("Available"); 
    } 
    else 
    { 
     MessageBox.Show("Not available"); 
    } 
} 
+1

Funziona solo per una rete. Se si dispone di più reti, l'evento verrà attivato solo quando tutte le reti sono offline. Questo non è utile nel mio caso (vedi la mia descrizione) –

+0

OOPs ho perso che :( – Anuraj

0

È possibile utilizzare il ping, ma vorrei anche costruire una semplice chiamata per restituire un "sì" se si è in linea. In questo modo puoi sapere se il server è attivo e che sta eseguendo il tuo codice. Inoltre chiamerei o fare un ping solo quando una risorsa di rete è necessaria e non continuamente.

0

Facendo un ping non è sicuramente l'opzione più pulita, soprattutto se si tratta di un server web. Alcuni host disabilitano la risposta al traffico ICMP, quindi è possibile eseguire il ping ma non ottenere una risposta. Che ne dici di gestire l'eccezione con garbo quando si verifica?

+1

Beh, in realtà non sto inviando un comando "ping". Invece io chiamo un webservice sul mio webserver. Questo mi dice se il mio WCF- I servizi sono ancora vivi :) –

8

Ho provato il link Webleeuw suggerito, ma che il codice ha bisogno anche tra i 4 e 10 secondi per notificare me quando collegare o scollegare il mio cavo. Ora, volevo sapere se si trattava solo del mio computer o installazione e ho scritto la mia classe Observer basata su NetworkInterface.GetAllNetworkInterfaces().

E: Funziona alla velocità della luce. La mia app reagisce con la stessa rapidità del vassoio. Il codice è lontano dal codice di produzione, è solo un rapido trucco. Ma questo è ciò che io voglio costruire su ora :)

using System; 
using System.Net.NetworkInformation; 
using Timer=System.Threading.Timer; 

namespace NetworkCheckApp 
{ 
public class NetworkStatusObserver 
{ 
    public event EventHandler<EventArgs> NetworkChanged; 

    private NetworkInterface[] oldInterfaces; 
    private Timer timer; 

    public void Start() 
    { 
     timer = new Timer(UpdateNetworkStatus, null, new TimeSpan(0, 0, 0, 0, 500), new TimeSpan(0, 0, 0, 0, 500)); 

     oldInterfaces = NetworkInterface.GetAllNetworkInterfaces(); 
    } 

    private void UpdateNetworkStatus(object o) 
    { 
     var newInterfaces = NetworkInterface.GetAllNetworkInterfaces(); 
     bool hasChanges = false; 
     if (newInterfaces.Length != oldInterfaces.Length) 
     { 
      hasChanges = true; 
     } 
     if (!hasChanges) 
     { 
      for (int i = 0; i < oldInterfaces.Length; i++) 
      { 
       if (oldInterfaces[i].Name != newInterfaces[i].Name || oldInterfaces[i].OperationalStatus != newInterfaces[i].OperationalStatus) 
       { 
        hasChanges = true; 
        break; 
       } 
      } 
     } 

     oldInterfaces = newInterfaces; 

     if (hasChanges) 
     { 
      RaiseNetworkChanged(); 
     } 
    } 

    private void RaiseNetworkChanged() 
    { 
     if (NetworkChanged != null) 
     { 
      NetworkChanged.Invoke(this, null); 
     } 
    } 
} 
} 
+1

Peccato che la mia modifica non sia stata in grado di aiutarti, ma la bella soluzione che ti sei fornito :). Potrei usarlo io stesso nel (vicino) futuro, quindi grazie per averlo fornito qui. – Webleeuw

2

La gente qui già detto, ma c'è una diference tra la disponibilità della rete e disponibilità di internet.
È possibile avere disponibilità di rete tra l'interfaccia di rete e il router locale, ma non disporre della disponibilità di Internet tra il router locale e il provider di servizi Internet (ISP).
C'è un altro problema che il test da ping vi racconterà la disponibilità di Internet, ma non di quello che interfaccia di rete fornisce, credo che l'unico modo è la forza ping ATTRAVERSO un'interfaccia ma isnot possibile su Windows.

Problemi correlati