Wie kann ich mit .NET am besten nach Internetverbindungen suchen?

237

Was ist der schnellste und effizienteste Weg, um die Internetverbindung in .NET zu überprüfen?

Mohit Deshpande
quelle
6
Wenn der Benutzer eine Internetverbindung hat. Wenn der Benutzer eine Verbindung zum Internet herstellen kann. Um ein E-Mail-Protokoll zu senden.
Mohit Deshpande
11
Senden Sie einfach die E-Mail. Wenn der Benutzer nicht verbunden ist, erhalten Sie wahrscheinlich eine Ausnahme (die Sie wahrscheinlich sowieso behandeln müssten).
Seth
15
Beachten Sie auch, dass es keine Möglichkeit zu überprüfen , ob der Benutzer ist mit dem Internet verbunden ist ; Alles, was Sie sagen können, ist, ob sie in der Vergangenheit verbunden waren . Angenommen, Sie hatten eine Methode: "bool c = IsConnected (); if (c) {DoSomething ();}" - zwischen dem Aufruf von IsConnected und DoSomething wurde möglicherweise der drahtlose Netzwerkrouter getrennt. IsConnected sollte eigentlich WasRecentlyConnected heißen.
Eric Lippert
Windows NLM APIsollte das Beste dafür sein. stackoverflow.com/questions/5405895/…
Mahbubur Rahman

Antworten:

292

So etwas sollte funktionieren.

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;
    }
}
ChaosPandion
quelle
18
Dies ist wahrscheinlich besser als das Pingen von Google, da wir meiner Meinung nach keine Garantie dafür haben, dass Google weiterhin auf Pings reagiert. Andererseits kann ich mir keine Welt vorstellen, in der www.google.com kein HTML zurückgibt :)
Daniel Vassallo
3
@ Daniel: wahr auf der einen Seite, aber auf der anderen Seite ist das Herunterladen der Website ein wenig Overhead imo
Leo
9
In beiden Fällen kein Grund, die 4 KB zurückzunehmen - verwenden Sie stattdessen einfach client.OpenRead (url). Wenn keine Ausnahme ausgelöst wird, konnte eine Verbindung hergestellt werden.
Josh M.
14
Das ist eigentlich nicht so effizient. Wenn ich das benutze, startet mein Programm länger als 1 Minute, wenn kein Internet vorhanden ist. Wahrscheinlich aufgrund des Versuchs, DNS aufzulösen. Pinging 8.8.8.8 (Google DNS) änderte es auf 3 Sekunden.
MadBoy
8
@ DanielVassallo I cannot image a world where www.google.com does not return some HTMLin China zum Beispiel ...
Jérôme MEVEL
84

Es gibt absolut keine Möglichkeit, zuverlässig zu überprüfen, ob eine Internetverbindung besteht oder nicht (ich nehme an, Sie meinen den Zugang zum Internet).

Sie können jedoch Ressourcen anfordern, die praktisch nie offline sind, z. B. Ping an google.com oder ähnliches. Ich denke, das wäre effizient.

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;
}
Löwe
quelle
24
+1 "Es gibt absolut keine Möglichkeit, zuverlässig zu überprüfen, ob eine Internetverbindung besteht"
woz
6
Sie müssen lediglich überprüfen, ob Google aktiv ist, wenn Sie einen Ping-Befehl gesendet haben. Wenn das Internet im nächsten Moment nach Ihrem erfolgreichen Ping ausfällt, was dann? Es macht keinen Sinn, dies vorher zu überprüfen.
Dbasnett
12
Und wie widerspricht dies der Hauptaussage meiner Antwort?
Leo
10
Die Verwendung von "google.com" dauert länger, da es gelöst werden muss. Stattdessen ist das direkte Pingen über IP schneller. Das Pingen an die öffentlichen DNS-IP-Adressen ( 8.8.8.8oder 8.8.4.4) von Google funktioniert für mich einwandfrei .
Mangesh
8
Ich möchte noch einmal darauf hinweisen, dass Beware - many schools and offices block the ping protocol.ich , wenn Sie diese Methode für eine Anwendung verwenden, die von Kunden verwendet wird, von dieser Methode zur Überprüfung des Internets abraten würde
Benutzer1
42

Anstatt zu prüfen, führen Sie einfach die Aktion aus (Webanforderung, E-Mail, FTP usw.) und bereiten Sie sich darauf vor, dass die Anforderung fehlschlägt. Dies müssen Sie trotzdem tun, auch wenn Ihre Prüfung erfolgreich war.

Folgendes berücksichtigen:

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

Wenn das Netzwerk ausgefallen ist, schlägt Ihre Aktion genauso schnell fehl wie ein Ping usw.

1 - start to perform action
2 - if the net is down(or goes down) the action will fail
dbasnett
quelle
9
Richtig! Tun Sie es einfach - aber seien Sie auf alle Ergebnisse vorbereitet.
Colonel Panic
3
Beachten Sie Folgendes: Sie müssen etwas tun, wenn das Netzwerk x x außerhalb der Zeit ausgefallen ist (z. B. Tracelog, Zurücksetzen des Routers)
Abir
2
Nicht das OP, aber der Grund, warum ich dies tun möchte, ist, den Standard 100 Sekunden zu vermeiden, wenn keine Internetverbindung verfügbar ist. Die HTTP-Anforderung wird in einem Hintergrundthread ausgeführt, sodass der UI-Thread nicht blockiert wird. Meine App kann jedoch erst beendet werden, wenn der Hintergrundthread von der HTTP-Anforderung zurückkehrt und beendet wird. Anstatt zu versuchen, einen Timeout-Wert für "Happy Medium" zu finden, möchte ich die Anfrage einfach ganz vermeiden, wenn ich wüsste, dass die Internetverbindung unterbrochen ist.
Scott Smith
2
Mein Punkt war, dass wir nicht berücksichtigen können, wann der Remote-Dienst verfügbar / nicht verfügbar sein könnte. Und was ist mit Websites, die nicht auf Pings reagieren?
Dbasnett
Ein weiterer Anwendungsfall ist ein Online-Checker, der mich benachrichtigt, sobald mein Internet wieder verfügbar ist
Ben Philipp,
28

NetworkInterface.GetIsNetworkAvailableist sehr unzuverlässig. Haben Sie nur eine VMware- oder eine andere LAN-Verbindung und es wird ein falsches Ergebnis zurückgegeben. Auch über die Dns.GetHostEntryMethode war ich nur besorgt darüber, ob die Test-URL in der Umgebung, in der meine Anwendung bereitgestellt werden soll, blockiert sein könnte.

Ein anderer Weg, den ich herausgefunden habe, ist die Verwendung der InternetGetConnectedStateMethode. Mein Code ist

[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);         
}
Kamran Shahid
quelle
Während des Tests stellte ich fest, dass InternetGetConnectedState true zurückgab, als VMWare Player installiert wurde (Internet getrennt). Musste es in Systemsteuerung \ Netzwerk und Internet \ Netzwerkverbindungen (VMNet1 und VMNet8) deaktivieren.
HockeyJ
Ok Justin Oringer. Obwohl ich es überprüft habe, aber erneut überprüfen muss
Kamran Shahid
2
Der beste Ansatz für mich ist, dass ich danach immer noch meine Service-Konnektivität überprüfe und dann die Routinen starte ... Ich wollte nur Ausnahmen vermeiden.
Wagner Bertolini Junior
4
Dieser Code prüft nur, ob das Netzwerkkabel eingesteckt ist.
HackerMan
14

Ein Test für die Internetverbindung durch Ping von Google:

new Ping().Send("www.google.com.mx").Status == IPStatus.Success
Jaime Macias
quelle
7
Eine Beschreibung zu dieser Antwort wäre für mehr Menschen von Vorteil als nur für den ursprünglichen Autor der Frage.
Boeckm
13
Achtung - viele Schulen und Büros blockieren das Ping-Protokoll. Dumm, ich weiß.
Colonel Panic
Ich kann die Ping-Klasse nicht finden. Kannst du mir bitte Helfen. Ich arbeite an UWP und die anderen Möglichkeiten, die Netzwerkinformationen
durchzugehen,
12

Ich bin nicht einverstanden mit Leuten, die sagen: "Was bringt es, vor dem Ausführen einer Aufgabe auf Konnektivität zu prüfen, da die Verbindung unmittelbar nach der Prüfung möglicherweise unterbrochen wird?" Sicherlich gibt es bei vielen Programmieraufgaben, die wir als Entwickler übernehmen, ein gewisses Maß an Unsicherheit, aber die Reduzierung der Unsicherheit auf ein Maß an Akzeptanz ist Teil der Herausforderung.

Ich bin kürzlich auf dieses Problem gestoßen, als ich eine Anwendung erstellt habe, die eine Zuordnungsfunktion enthält, die mit einem Online-Kachelserver verknüpft ist. Diese Funktionalität sollte deaktiviert werden, wenn ein Mangel an Internetverbindung festgestellt wurde.

Einige der Antworten auf dieser Seite waren sehr gut, verursachten jedoch viele Leistungsprobleme wie das Aufhängen, hauptsächlich im Falle fehlender Konnektivität.

Hier ist die Lösung, die ich mithilfe einiger dieser Antworten und meiner Kollegen verwendet habe:

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

Ich habe alle oben aufgeführten Optionen gesehen und die einzige praktikable Option, um zu überprüfen, ob das Internet verfügbar ist oder nicht, ist die Option "Ping". Das Importieren [DllImport("Wininet.dll")]und / System.Net.NetworkInformation.NetworkInterface.GetAllNetworkInterfaces() oder eine andere Variante der NetworkInterface Klasse funktioniert nicht gut, um die Verfügbarkeit des Netzwerks zu ermitteln. Diese Methoden prüfen nur, ob das Netzwerkkabel eingesteckt ist oder nicht.

Die "Ping-Option"

if(Verbindung ist verfügbar) wird zurückgegeben true

if(Verbindung ist nicht verfügbar und das Netzwerkkabel ist eingesteckt) kehrt zurück false

if(Netzwerkkabel ist nicht eingesteckt) Throws an exception

Das NetworkInterface

if(Internet ist verfügbar) Rückgabe True

if(Internet ist nicht verfügbar und Netzwerkkabel ist eingesteckt) Rückgabe True

if(Netzwerkkabel ist nicht eingesteckt) wird zurückgegeben false

Der [DllImport ("Wininet.dll")]

if(Internet ist verfügbar) Rückgabe True

if(Internet ist nicht verfügbar und Netzwerkkabel ist eingesteckt) Rückgabe True

if(Netzwerkkabel ist nicht eingesteckt) wird zurückgegeben false

Im Falle von [DllImport("Wininet.dll")] und NetworkInterface Es gibt keine Möglichkeit zu wissen, ob eine Internetverbindung verfügbar ist.

HackerMan
quelle
Dies ist nicht wahr, ich habe Wininet.dll importiert, das Netzwerkkabel eingesteckt und das richtige Ergebnis für das Szenario Internet erhalten, das nicht verfügbar ist.
Waldemar Gałęzinowski
8

Löst nicht das Problem, dass das Netzwerk zwischen dem Überprüfen und Ausführen Ihres Codes ausfällt, ist aber ziemlich zuverlässig

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;
}
Anton
quelle
Tolle Idee, aber wie Sie sagten, ist es vielleicht nicht perfekt. Sie können die gesendeten / empfangenen Bytes auch für zukünftige Überprüfungen zwischenspeichern. Immer noch nicht perfekt.
Todd
Dieser Code funktioniert nicht, bitte korrigieren. Es wird nur geprüft, ob das Netzwerkkabel eingesteckt ist oder nicht.
HackerMan
5

Durch Ping von google.com wird eine Abhängigkeit von der DNS-Auflösung eingeführt. Ping 8.8.8.8 ist in Ordnung, aber Google ist einige Sprünge von mir entfernt. Alles, was ich tun muss, ist, das nächstgelegene im Internet zu pingen.

Ich kann die TTL-Funktion von Ping verwenden, um Hop Nr. 1, dann Hop Nr. 2 usw. zu pingen, bis ich eine Antwort von etwas erhalte, das sich an einer routbaren Adresse befindet. Wenn sich dieser Knoten an einer routbaren Adresse befindet, befindet er sich im Internet. Für die meisten von uns ist Hop Nr. 1 unser lokales Gateway / Router, und Hop Nr. 2 ist der erste Punkt auf der anderen Seite unserer Glasfaserverbindung oder was auch immer.

Dieser Code funktioniert für mich und reagiert schneller als einige der anderen Vorschläge in diesem Thread, da er im Internet pingt, was mir am nächsten ist.

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;
        }
    }
}
Jinlye
quelle
4

So wird es in Android implementiert.

Als Proof of Concept habe ich diesen Code in C # übersetzt:

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
    }
}
Breez
quelle
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;
    }
}
Shai Segev
quelle
2

Eine weitere Option ist die Network List Manager-API, die für Vista und Windows 7 verfügbar ist. MSDN-Artikel hier . In diesem Artikel finden Sie einen Link zum Herunterladen von Codebeispielen, mit denen Sie Folgendes tun können:

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

Stellen Sie sicher, dass Sie auf der Registerkarte COM einen Verweis auf Network List 1.0 Type Library hinzufügen, der als NETWORKLIST angezeigt wird.

gierow
quelle
7
eeeeww. Verwenden Sie die COM-Hölle in .NET?
Jgauffin
@jgauffin Kannst du vielleicht erklären, warum man COM in .NET vermeiden sollte? Im Vergleich zu den anderen Lösungen, die ich gefunden habe, scheint die COM-Lösung ziemlich gut zu funktionieren.
Unentschlossenheit
2

Vermeiden Sie das Testen von Verbindungen, indem Sie die Ausnahme abfangen. weil wir wirklich erwarten, dass wir manchmal die Netzwerkverbindung verlieren können.

 if (NetworkInterface.GetIsNetworkAvailable() &&
     new Ping().Send(new IPAddress(new byte[] { 8, 8, 8, 8 }),2000).Status == IPStatus.Success)
 //is online
 else
 //is offline
Shervin Ivari
quelle
1
Woher kommt das NetworkInterface? EDIT: Ich finde es: System.Net.NetworkInformation
inspir_coding
1

Ich persönlich finde die Antwort von Anton und moffeltje am besten, aber ich habe eine Überprüfung hinzugefügt, um virtuelle Netzwerke auszuschließen, die von VMWare und anderen eingerichtet wurden.

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));
}
Spegeli
quelle
Zu Ihrer Information aus den GetIsNetworkAvailable () -Dokumenten: Eine Netzwerkverbindung gilt als verfügbar, wenn eine Netzwerkschnittstelle als "up" markiert ist und keine Loopback- oder Tunnelschnittstelle ist. Ich weiß nicht, ob virtuell immer im Namen oder in der Beschreibung der Schnittstelle enthalten sein wird. Ist das 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");
Hari Prasath
quelle
1
Können Sie Informationen hinzufügen, die sich auf die Geschwindigkeit beziehen und wie dies besser ist als bei anderen veröffentlichten Lösungen? Dies hilft Ihrer Antwort bei der vollständigen Beantwortung der Frage.
Ren
8
Das Problem bei dieser Option ist, dass bbdies auch dann der Fall ist, wenn das Netzwerk nicht mit dem Internet verbunden ist.
halfpastfour.am
2
Es stimmt zwar, dass dies die Frage nicht direkt beantwortet, aber ich denke, es ist immer noch nützlich, GetIsNetworkAvailable als Vorabprüfung zu verwenden, bevor Sie versuchen, Google usw. anzupingen
Ben Hughes
3
Dieser Code gibt nicht an, ob eine Internetverbindung verfügbar ist oder nicht. Wenn Sie ein Netzwerkkabel ohne Internet anschließen, wird true zurückgegeben.
HackerMan
1

Multithread-Version von 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";
          }
      }
  }
Nime Cloud
quelle
0

Ich würde nicht denken, dass es unmöglich ist, nur nicht einfach.

Ich habe so etwas gebaut, und ja, es ist nicht perfekt, aber der erste Schritt ist wichtig: zu überprüfen, ob es eine Netzwerkverbindung gibt. Die Windows-API macht keinen großartigen Job. Warum also nicht einen besseren Job machen?

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

Es ist ziemlich einfach, aber es hilft wirklich, die Qualität der Prüfung zu verbessern, insbesondere wenn Sie verschiedene Proxy-Konfigurationen überprüfen möchten.

So:

  • Überprüfen Sie, ob eine Netzwerkverbindung besteht (machen Sie dies wirklich gut, lassen Sie möglicherweise sogar Protokolle an Entwickler zurücksenden, wenn Fehlalarme vorliegen, um die NetworkIsAvailable-Funktion zu verbessern).
  • HTTP-Ping
  • (Durchlaufen Sie die Proxy-Konfigurationen mit jeweils HTTP-Pings.)
Todd
quelle
1
@ Hackerman Dies ist der nicht offensichtliche erste Schritt. Codierer können als zweiten Schritt einen schnellen Ping an ihren eigenen Server ausführen, wenn dieser den Wert true zurückgibt. Wichtig ist, dass dies eine Alternative zur fehlerhaften Windows-API-Methode darstellt. Der Rest sind Details.
Todd
3
Fälschen. Wenn keine Netzwerkschnittstelle vorhanden ist, gibt es definitiv kein Internet. Die Benutzeroberfläche kann sofort ohne Verzögerung aktualisiert werden, ohne weitere Überprüfungen auf anderen Hosts.
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;
    }
}
Salih Alija
quelle
Bitte kommentieren Sie Ihre Antwort. Antworten mit nur Code sind nicht zulässig.
Ganchito55
Es ist ziemlich selbsterklärend, um der Polizei willen zu überwachen?
rollt
0

Verwenden Sie NetworkMonitor, um den Netzwerkstatus und die Internetverbindung zu überwachen.

Stichprobe:

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

quelle
Gute Idee, aber prüft die Netzwerkverfügbarkeit, nicht die Internetverfügbarkeit
John Demetriou
Diese Klasse prüft auch die Verfügbarkeit des Internets: SourceCode
Die Sache ist, ich habe es versucht, aber es wurde nur ausgelöst, wenn kein Netzwerk verfügbar war
John Demetriou
0

Einführung

In einigen Szenarien müssen Sie mithilfe von C # -Code in Windows-Anwendungen überprüfen, ob das Internet verfügbar ist oder nicht. In diesen Situationen ist es möglicherweise obligatorisch, eine Datei über das Internet in Windows-Formularen herunterzuladen oder hochzuladen oder Daten aus einer Datenbank abzurufen, die sich an einem entfernten Standort befindet.

Es gibt einige Möglichkeiten, die Internetverfügbarkeit mithilfe von C # anhand des dahinter stehenden Codes zu überprüfen. Alle diese Möglichkeiten werden hier einschließlich ihrer Einschränkungen erläutert.

  1. InternetGetConnectedState (wininet)

Mit der 'wininet'-API kann überprüft werden, ob das lokale System über eine aktive Internetverbindung verfügt oder nicht. Der dafür verwendete Namespace ist 'System.Runtime.InteropServices' und importiert die DLL 'wininet.dll' mit DllImport. Erstellen Sie anschließend eine boolesche Variable mit extern static mit dem Funktionsnamen InternetGetConnectedState mit zwei Parameter description und reservedValue, wie im Beispiel gezeigt.

Hinweis: Der Modifikator extern wird verwendet, um eine extern implementierte Methode zu deklarieren. Der externe Modifikator wird häufig mit dem DllImport-Attribut verwendet, wenn Sie Interop-Dienste zum Aufrufen von nicht verwaltetem Code verwenden. In diesem Fall muss die Methode auch als statisch deklariert werden.

Erstellen Sie als Nächstes eine Methode mit dem Namen 'IsInternetAvailable' als Booleschen Wert. Die obige Funktion wird bei dieser Methode verwendet, die den Internetstatus des lokalen Systems zurückgibt

[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

Im folgenden Beispiel wird mithilfe der GetIsNetworkAvailable-Methode ermittelt, ob eine Netzwerkverbindung verfügbar ist.

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

Anmerkungen (gemäß MSDN): Eine Netzwerkverbindung gilt als verfügbar, wenn eine Netzwerkschnittstelle als "up" markiert ist und keine Loopback- oder Tunnelschnittstelle ist.

Es gibt viele Fälle, in denen ein Gerät oder Computer nicht mit einem nützlichen Netzwerk verbunden ist, aber dennoch als verfügbar angesehen wird und GetIsNetworkAvailable true zurückgibt. Wenn beispielsweise das Gerät, auf dem die Anwendung ausgeführt wird, mit einem drahtlosen Netzwerk verbunden ist, für das ein Proxy erforderlich ist, der Proxy jedoch nicht festgelegt ist, gibt GetIsNetworkAvailable true zurück. Ein weiteres Beispiel dafür, wann GetIsNetworkAvailable true zurückgibt, ist, wenn die Anwendung auf einem Computer ausgeführt wird, der mit einem Hub oder Router verbunden ist, auf dem der Hub oder Router die Upstream-Verbindung verloren hat.

  1. Pingen Sie einen Hostnamen im Netzwerk

Mit den Klassen Ping und PingReply kann eine Anwendung ermitteln, ob auf einen Remotecomputer über das Netzwerk zugegriffen werden kann, indem sie eine Antwort vom Host erhält. Diese Klassen sind im System.Net.NetworkInformation-Namespace verfügbar. Das folgende Beispiel zeigt, wie Sie einen Host anpingen.

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

Anmerkungen (gemäß MSDN): Anwendungen verwenden die Ping-Klasse, um festzustellen, ob ein Remotecomputer erreichbar ist. Die Netzwerktopologie kann bestimmen, ob Ping erfolgreich einen Remote-Host kontaktieren kann. Das Vorhandensein und die Konfiguration von Proxys, NAT-Geräten (Network Address Translation) oder Firewalls kann den Erfolg von Ping verhindern. Ein erfolgreicher Ping zeigt nur an, dass der Remote-Host im Netzwerk erreichbar ist. Das Vorhandensein von Diensten höherer Ebene (z. B. eines Webservers) auf dem Remote-Host kann nicht garantiert werden.

Kommentare / Vorschläge sind eingeladen. Viel Spaß beim Codieren ......!

Khuram Shahzad
quelle
-1

Für meine Anwendung testen wir auch per Download winzige Datei.

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

Ebenfalls. Einige ISPs verwenden möglicherweise den mittleren Server, um Dateien zwischenzuspeichern. Fügen Sie zufällige nicht verwendete Parameter hinzu, z. https://www.microsoft.com/favicon.ico?req=random_number Kann das Caching verhindern.

user282341
quelle
-1

Ich habe Probleme mit dieser Methode auf meinem 3G-Router / Modem, da der Router die Seite auf die Antwortseite umleitet, wenn das Internet nicht verbunden ist, sodass Sie immer noch Dampf bekommen und Ihr Code denkt, dass es Internet gibt. Äpfel (oder andere) haben eine Hot-Spot-Seite, die immer eine bestimmte Antwort zurückgibt. Das folgende Beispiel gibt die Antwort "Erfolg" zurück. Sie werden also genau sicher sein, dass Sie eine Verbindung zum Internet herstellen und eine echte Antwort erhalten können!

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;
}
Yusuf GURDAG
quelle
-2

Ich habe drei Tests für eine Internetverbindung.

  • Referenz System.NetundSystem.Net.Sockets
  • Fügen Sie die folgenden Testfunktionen hinzu:

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

Durchführen der Tests

Wenn Sie ein Dictionaryvon erstellen Stringund Booleanaufrufen CheckList, können Sie die Ergebnisse jedes Tests hinzufügen CheckList.

Führen Sie nun jede Schleife KeyValuePairmit einer for...eachSchleife durch.

Wenn CheckListein Valuevon enthält true, wissen Sie, dass eine Internetverbindung besteht.

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

Das funktioniert

slayerIQ
quelle
46
Wenn Sie die IP-Adresse von Google in Ihrem DNS-Cache haben, wird keine DNS-Anfrage gesendet, sodass auch dann true zurückgegeben werden kann, wenn Sie nicht verbunden sind
Thomas Levesque,