wake-up-neo.com

Was ist der beste Weg, um die Internetverbindung mit .NET zu überprüfen?

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

192
Mohit Deshpande

So etwas sollte funktionieren.

System.Net.WebClient

public static bool CheckForInternetConnection()
{
    try
    {
        using (var client = new WebClient())
        using (client.OpenRead("http://clients3.google.com/generate_204"))
        {
            return true;
        }
    }
    catch
    {
        return false;
    }
}
238
ChaosPandion

Es gibt absolut keine Möglichkeit, dass Sie zuverlässig prüfen, ob eine Internetverbindung besteht oder nicht (ich nehme an, Sie meinen einen Internetzugang).

Sie können jedoch Ressourcen anfordern, die so gut wie nie offline sind, wie z. B. 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;
}
70
Leo

Statt zu prüfen, führen Sie einfach die Aktion aus (Webanforderung, E-Mail, FTP usw.) und seien Sie darauf vorbereitet, dass die Anforderung fehlschlägt, was Sie trotzdem tun müssen, 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 ausfällt, 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
35
dbasnett

NetworkInterface.GetIsNetworkAvailable ist sehr unzuverlässig. Habe nur eine VMware- oder andere LAN-Verbindung und es wird ein falsches Ergebnis zurückgegeben. __ Auch über die Dns.GetHostEntry-Methode war ich nur besorgt darüber, ob die Test-URL in der Umgebung blockiert werden könnte, in der meine Anwendung bereitgestellt wird.

Eine andere Methode, die ich herausfand, ist die Verwendung der InternetGetConnectedState-Methode . 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);         
}
22
Kamran Shahid

Ich stimme nicht mit Leuten überein, die sagen: "Was ist der Punkt bei der Überprüfung der Konnektivität, bevor eine Aufgabe ausgeführt wird, da unmittelbar nach der Überprüfung die Verbindung verloren gehen kann?" . Sicherlich besteht bei vielen Programmieraufgaben, die wir als Entwickler haben, eine gewisse Unsicherheit unternehmen, aber die Verringerung der Unsicherheit auf ein Maß an Akzeptanz ist Teil der Herausforderung.

Ich bin vor kurzem auf dieses Problem gestoßen, als ich eine Anwendung erstellte, die eine Zuordnungsfunktion aufwies, die mit einem Online-Kachel-Server verbunden war. Diese Funktion sollte deaktiviert werden, wenn eine fehlende Internetverbindung festgestellt wurde.

Einige der Antworten auf dieser Seite waren sehr gut, führten jedoch zu zahlreichen Leistungsproblemen, z. B. zum Erhängen, vor allem im Fall der fehlenden Konnektivität.

Hier ist die Lösung, die ich mit Hilfe 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
            }));
        }
    }
11
PJRobot

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

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

Behebt nicht das Problem, dass das Netzwerk zwischen Überprüfung und Ausführung 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;
}
8
Anton

Ich habe alle oben aufgeführten Optionen gesehen und die einzig mögliche Option, um zu überprüfen, ob das Internet verfügbar ist oder nicht, ist die "Ping" -Option. _. Importieren von [DllImport("Wininet.dll")] und System.Net.NetworkInformation.NetworkInterface.GetAllNetworkInterfaces() oder jede andere Variation der NetworkInterface-Klasse funktioniert nicht gut bei der Erkennung die Verfügbarkeit des Netzwerks. Diese Methoden prüfen nur, ob das Netzwerkkabel angeschlossen ist oder nicht.

Die "Ping-Option"

if (Verbindung ist verfügbar) gibt true zurück

if (Die Verbindung ist nicht verfügbar und das Netzwerkkabel ist angeschlossen.) false

if (Netzwerkkabel ist nicht angeschlossen) Throws an exception

Das NetworkInterface

if (Internet ist verfügbar) Gibt True zurück

if (Internet ist nicht verfügbar und Netzwerkkabel ist angeschlossen.) True

if (Netzwerkkabel ist nicht angeschlossen) gibt false zurück

Die [DllImport ("Wininet.dll")]

if (Internet ist verfügbar) Gibt True zurück

if (Internet ist nicht verfügbar und Netzwerkkabel ist angeschlossen.) True

if (Netzwerkkabel ist nicht angeschlossen) gibt false zurück

Im Fall von [DllImport("Wininet.dll")] und NetworkInterface kann nicht festgestellt werden, ob eine Internetverbindung verfügbar ist.

7
HackerMan
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;
    }
}
3
Shai Segev

Hier ist wie es in Android implementiert ist.

Als Beweis für das Konzept 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
    }
}
3
breez

Pinging google.com führt eine Abhängigkeit von der DNS-Auflösung ein. Ping 8.8.8.8 ist in Ordnung, aber Google ist mehrere Hops von mir entfernt. Alles, was ich tun muss, ist, das nächstgelegene Ding aus dem Internet zu pingen. 

Ich kann die Funktion TTL von Ping verwenden, um Hopfen Nr. 1, dann Nr. 2 usw. zu pingen, bis ich eine Antwort von etwas bekomme, das sich auf 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 # 1 unser lokales Gateway/Router, und Hop # 2 ist der erste Punkt auf der anderen Seite unserer Glasfaserverbindung oder was auch immer. 

Dieser Code funktioniert für mich und antwortet schneller als einige der anderen Vorschläge in diesem Thread, da er das Ping-Signal auf das Internet überträgt, das mir am nächsten liegt.

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

Ich persönlich finde die Antwort auf Anton und moffeltje am besten, aber ich habe einen Haken hinzugefügt, um die von VMWare und anderen eingerichteten virtuellen Netzwerke auszuschließen.

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

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 die Network List 1.0-Typenbibliothek hinzufügen ..., die als NETWORKLIST angezeigt wird.

1
gierow

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

Probe:

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

Versuche dies:

 using System.Net.NetworkInformation;
 bool isNetAvailable = NetworkInterface.GetIsNetworkAvailable();
0
Shaahin
bool bb = System.Net.NetworkInformation.NetworkInterface.GetIsNetworkAvailable();

if (bb == true)
    MessageBox.Show("Internet connections are available");
else
    MessageBox.Show("Internet connections are not available");
0
Hari Prasath
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;
    }
}
0
Salih Alija

Wenn Sie den Benutzer benachrichtigen möchten oder Maßnahmen ergreifen, wenn eine Netzwerk-/Verbindungsänderung auftritt.
Verwenden Sie die NLM-API:

0
Ansary Ans21

Multi-Thread-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";
          }
      }
  }
0
Nime Cloud

Ich würde es nicht für unmöglich halten, nur nicht unkompliziert.

Ich habe so etwas gebaut, und ja, es ist nicht perfekt, aber der erste Schritt ist wichtig: zu prüfen, ob Netzwerkverbindungen vorhanden sind. Die Windows-API ist nicht besonders gut. Warum also nicht besser?

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 Netzwerkverbindung besteht (machen Sie das wirklich gut, vielleicht lassen sich sogar Protokolle an Entwickler zurückschicken, wenn Fehlalarme vorhanden sind, um die Funktion NetworkIsAvailable zu verbessern.)
  • HTTP-Ping
  • (Wechseln Sie durch Proxy-Konfigurationen mit jeweils HTTP-Pings)
0
Todd