Jaki jest najlepszy sposób sprawdzenia łączności z Internetem za pomocą platformy .NET?

237

Jaki jest najszybszy i najskuteczniejszy sposób sprawdzenia łączności z Internetem w .NET?

Mohit Deshpande
źródło
6
Jeśli użytkownik ma połączenie internetowe. Jeśli użytkownik może połączyć się z Internetem. Aby wysłać dziennik e-mail.
Mohit Deshpande
11
Po prostu wyślij e-mail. Jeśli użytkownik nie jest połączony, prawdopodobnie otrzymasz jakiś wyjątek (z którym prawdopodobnie i tak musiałbyś sobie poradzić).
Seth
15
Pamiętaj również, że nie ma sposobu, aby sprawdzić, czy użytkownik jest podłączony do Internetu; wszystko, co możesz powiedzieć, to czy były one połączone w przeszłości . Załóżmy, że masz metodę: „bool c = IsConnected (); if (c) {DoSomething ();}” - między wywołaniem IsConnected a DoSomething router sieci bezprzewodowej mógł być odłączony. IsConnected naprawdę powinien nazywać się WasRecentlyConnected.
Eric Lippert,
Windows NLM APIpowinno być najlepsze do tego. stackoverflow.com/questions/5405895/…
Mahbubur Rahman

Odpowiedzi:

292

Coś takiego powinno działać.

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
źródło
18
Jest to prawdopodobnie lepsze niż pingowanie Google, ponieważ myślę, że nie mamy żadnej gwarancji, że Google nadal odpowiada na pingi. Z drugiej strony nie mogę sobie wyobrazić świata, w którym www.google.com nie zwraca kodu HTML :)
Daniel Vassallo
3
@Daniel: z jednej strony prawda, ale z drugiej strony ściąganie strony internetowej to trochę narzuta
Leo
9
Tak czy inaczej, nie ma powodu, aby cofać 4KB - po prostu użyj zamiast tego client.OpenRead (url). Jeśli nie zgłasza wyjątku, mógł się połączyć.
Josh M.
14
To nie jest tak wydajne. Korzystanie z tego powoduje, że mój program uruchamia się ponad 1 minutę, jeśli nie ma internetu. Prawdopodobnie z powodu próby rozwiązania DNS. Pinging 8.8.8.8 (google dns) zmieniło go na 3 sekundy.
MadBoy
8
@DanielVassallo I cannot image a world where www.google.com does not return some HTMLw Chinach, na przykład ...
Jérôme MEVEL
84

Nie ma absolutnie żadnego sposobu na niezawodne sprawdzić, czy jest połączenie z Internetem, czy nie (zakładam, że masz na myśli dostęp do Internetu).

Możesz jednak poprosić o zasoby, które praktycznie nigdy nie są w trybie offline, takie jak pingowanie google.com lub coś podobnego. Myślę, że to byłoby skuteczne.

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;
}
Lew
źródło
24
+1 „Nie ma absolutnie żadnego sposobu, aby rzetelnie sprawdzić, czy jest połączenie z Internetem”
woz
6
Wszystko to polega na sprawdzeniu, czy Google działa, gdy go pingujesz. Jeśli w następnej chwili po udanym pingowaniu internet przestanie działać, to co? Nie ma sensu sprawdzać przed zrobieniem tego.
dbasnett
12
I w jaki sposób jest to sprzeczne z głównym stwierdzeniem mojej odpowiedzi?
Lew
10
Korzystanie z „google.com” zajmie więcej czasu, ponieważ należy je rozwiązać. Zamiast tego pingowanie bezpośrednio przy użyciu IP będzie szybsze. Pingowanie do publicznych adresów IP Google DNS ( 8.8.8.8lub 8.8.4.4) działa dla mnie dobrze.
Mangesh
8
Chciałbym powtórzyć, że Beware - many schools and offices block the ping protocol.jeśli używasz tej metody do aplikacji, która będzie używana przez klientów, odradzam tę metodę sprawdzania Internetu
użytkownik 1
42

Zamiast sprawdzania, po prostu wykonaj akcję (żądanie sieciowe, poczta, ftp itp.) I przygotuj się na niepowodzenie żądania, co i tak musisz zrobić, nawet jeśli sprawdzenie się powiedzie.

Rozważ następujące:

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

Jeśli sieć nie działa, działanie zakończy się niepowodzeniem tak szybko, jak ping itp.

1 - start to perform action
2 - if the net is down(or goes down) the action will fail
dbasnett
źródło
9
Dobrze! Po prostu zrób to - ale bądź przygotowany na wszystkie wyniki.
Pułkownik Panic
3
Zastanów się: Musisz coś zrobić, jeśli sieć nie działa przez x czasu (np. Tracelog, reset routera)
Abir
2
Nie PO, ale chcę to zrobić, aby UNIKAĆ DOMYŚLNEGO 100 DRUGIEGO CZASU, jeśli połączenie z Internetem nie jest dostępne. Żądanie HTTP jest wykonywane w wątku w tle, więc wątek interfejsu użytkownika nie jest blokowany, ale moja aplikacja nie może wyjść, dopóki wątek w tle nie powróci z żądania HTTP i nie zakończy działania. Zamiast próbować znaleźć jakąś wartość „szczęśliwego średniego” limitu czasu, chciałbym po prostu całkowicie uniknąć żądania, gdybym wiedział, że połączenie internetowe nie działa.
Scott Smith
2
Chodzi mi o to, że nie możemy uwzględnić, kiedy zdalna usługa może stać się dostępna / niedostępna. A co z witrynami, które nie reagują na pingi?
dbasnett
Innym zastosowaniem jest przypadek sprawdzania online, która będzie ostrzegać mnie, jak tylko mój internet jest z powrotem w górę
Ben Philipp
28

NetworkInterface.GetIsNetworkAvailablejest bardzo zawodny. Wystarczy mieć jakieś VMware lub inne połączenie LAN, a ono zwróci zły wynik. Również o Dns.GetHostEntrymetodę martwiłem się tylko, czy testowy adres URL może zostać zablokowany w środowisku, w którym moja aplikacja ma zostać wdrożona.

Więc innym sposobem, który odkryłem, jest użycie InternetGetConnectedStatemetody. Mój kod to

[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
źródło
Podczas testów stwierdziłem, że funkcja InternetGetConnectedState zwróciła wartość true, gdy zainstalowano odtwarzacz VMWare (Internet odłączony). Musiałem go wyłączyć w Panelu sterowania \ Sieć i Internet \ Połączenia sieciowe (VMNet1 i VMNet8).
HockeyJ
Ok Justin Oringer. Chociaż sprawdziłem to, ale muszę to zweryfikować ponownie
Kamran Shahid
2
Najlepsze dla mnie podejście, nadal sprawdzam łączność z usługą, a następnie uruchamiam procedury ... Chciałem tylko uniknąć wyjątków.
Wagner Bertolini Junior
4
Ten kod sprawdza tylko, czy kabel sieciowy jest podłączony.
HackerMan
14

Test połączenia internetowego przez pingowanie Google:

new Ping().Send("www.google.com.mx").Status == IPStatus.Success
Jaime Macias
źródło
7
Opis zgodny z tą odpowiedzią byłby korzystniejszy dla większej liczby osób niż tylko oryginalny autor pytania.
Boeckm
13
Uwaga - wiele szkół i biur blokuje protokół ping. Głupia, wiem.
Pułkownik Panic
Nie mogę znaleźć klasy ping. Czy mógłbyś mi pomóc. Pracuję nad UWP, a poza tym przeglądanie informacji o sieci nie działa
iam.Carrot
12

Nie zgadzam się z osobami, które stwierdzają: „Po co sprawdzać łączność przed wykonaniem zadania, ponieważ natychmiast po sprawdzeniu połączenie może zostać utracone”. Z pewnością w wielu zadaniach programistycznych podejmujemy się, jako programiści, pewien stopień niepewności, ale ograniczanie niepewności do poziomu akceptacji jest częścią wyzwania.

Niedawno napotkałem ten problem podczas tworzenia aplikacji, która zawiera funkcję mapowania, która łączy się z serwerem kafelków on-line. Funkcjonalność ta miała zostać wyłączona tam, gdzie zauważono brak połączenia z Internetem.

Niektóre odpowiedzi na tej stronie były bardzo dobre, ale spowodowały jednak wiele problemów z wydajnością, takich jak zawieszanie się, głównie w przypadku braku łączności.

Oto rozwiązanie, z którego ostatecznie skorzystałem, korzystając z niektórych z tych odpowiedzi i moich kolegów:

         // 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
źródło
11

Widziałem wszystkie opcje wymienione powyżej, a jedyną realną opcją sprawdzenia, czy internet jest dostępny, czy nie, jest opcja „ping”. Importowanie [DllImport("Wininet.dll")]i / System.Net.NetworkInformation.NetworkInterface.GetAllNetworkInterfaces() lub jakakolwiek inna odmiana NetworkInterface klasy nie działa dobrze w wykrywaniu dostępności sieci. Te metody sprawdzają tylko, czy kabel sieciowy jest podłączony czy nie.

„Opcja pingowania”

if(Połączenie jest dostępne) zwraca true

if(Połączenie nie jest dostępne, a kabel sieciowy jest podłączony) powraca false

if(Kabel sieciowy nie jest podłączony) Throws an exception

Interfejs sieciowy

if(Internet jest dostępny) Zwraca True

if(Internet nie jest dostępny, a kabel sieciowy jest podłączony) Zwraca True

ifZwraca komunikat (Kabel sieciowy nie jest podłączony) false

[DllImport („Wininet.dll”)]

if(Internet jest dostępny) Zwraca True

if(Internet nie jest dostępny, a kabel sieciowy jest podłączony) Zwraca True

ifZwraca komunikat (Kabel sieciowy nie jest podłączony) false

Tak więc w przypadku [DllImport("Wininet.dll")] i NetworkInterface Nie ma możliwości sprawdzenia, czy połączenie internetowe jest dostępne.

HackerMan
źródło
To nie jest prawda, zaimportowałem plik Wininet.dll, podłączyłem kabel sieciowy i otrzymałem prawidłowy wynik w przypadku braku dostępu do Internetu w scenariuszu.
Waldemar Gałęzinowski
8

Nie rozwiązuje problemu awarii sieci między sprawdzaniem a uruchamianiem kodu, ale jest dość niezawodny

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
źródło
Świetny pomysł, ale jak powiedziałeś, może nie być idealny. Możesz buforować bajty wysłane / odebrane, a także do przyszłych kontroli. Nadal jednak nie idealny.
Todd
Ten kod nie działa. Popraw. Sprawdza tylko, czy kabel sieciowy jest podłączony czy nie.
HackerMan
5

Pinging google.com wprowadza zależność od rozpoznawania nazw DNS. Pingowanie 8.8.8.8 jest w porządku, ale Google jest o kilka kroków ode mnie. Wszystko, co muszę zrobić, to pingować najbliższą rzecz do mnie, która jest w Internecie.

Mogę używać funkcji Ping TTL do pingowania przeskoku 1, następnie przeskoku 2 itd., Dopóki nie otrzymam odpowiedzi z czegoś, co znajduje się na adresie routowalnym; jeśli ten węzeł znajduje się na routowalnym adresie, to znajduje się w Internecie. Dla większości z nas przeskakiwanie nr 1 będzie naszą lokalną bramą / routerem, a przeskakiwanie nr 2 będzie pierwszym punktem po drugiej stronie naszego połączenia światłowodowego.

Ten kod działa dla mnie i reaguje szybciej niż niektóre inne sugestie w tym wątku, ponieważ pinguje wszystko, co jest najbliżej mnie w Internecie.

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
źródło
4

Oto jak jest zaimplementowany w systemie Android.

Jako dowód koncepcji przetłumaczyłem ten kod na 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
    }
}
breez
źródło
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
źródło
2

Inną opcją jest interfejs API Network List Manager, który jest dostępny dla systemów Vista i Windows 7. Artykuł MSDN tutaj . W artykule znajduje się link do pobierania próbek kodu, które pozwalają to zrobić:

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

Pamiętaj, aby dodać odwołanie do Listy typów sieci Lista 1.0 z zakładki COM ..., która pojawi się jako LISTA SIECI.

gierow
źródło
7
eeeeww. Używasz piekła COM w .NET?
jgauffin
@jgauffin Czy możesz wyjaśnić, dlaczego należy unikać COM w .NET? W porównaniu z innymi rozwiązaniami, które znalazłem, rozwiązanie COM wydaje się działać całkiem dobrze.
inccitus
2

Staraj się unikać testowania połączeń, wychwytując wyjątek. ponieważ naprawdę oczekujemy, że czasami możemy utracić połączenie sieciowe.

 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
źródło
1
Skąd pochodzi interfejs sieciowy? EDYCJA: Uważam to: System.Net.NetworkInformation
inspire_coding
1

Osobiście najlepiej znajduję odpowiedź Antona i moffeltje , ale dodałem zaznaczenie, aby wykluczyć sieci wirtualne skonfigurowane przez VMWare i inne.

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
źródło
FYI z dokumentów GetIsNetworkAvailable (): Połączenie sieciowe jest uważane za dostępne, jeśli jakikolwiek interfejs sieciowy jest oznaczony jako „up” i nie jest interfejsem pętli zwrotnej ani tunelowania. Nie wiem, czy wirtualny zawsze będzie w nazwie lub opisie interfejsu. Czy to 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
źródło
1
Czy możesz dodać informacje dotyczące szybkości tego i tego, jak jest to lepsze niż w przypadku innych opublikowanych rozwiązań. Pomoże to w udzieleniu pełnej odpowiedzi na pytanie.
Ren
8
Problem z tą opcją jest taki bb że nadal byłby prawdziwy, nawet gdy sieć nie jest połączona z Internetem.
halfpastfour.am
2
Chociaż prawdą jest, że nie odpowiada to bezpośrednio na pytanie, myślę, że nadal warto używać GetIsNetworkAvailable jako wstępnej kontroli przed próbą wysłania polecenia ping do Google itp.
Ben Hughes,
3
Ten kod nie wskazuje, czy połączenie internetowe jest dostępne, czy nie. Jeśli podłączysz kabel sieciowy bez internetu, zwróci wartość true.
HackerMan
1

Wielowątkowa wersja 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
źródło
0

Nie sądziłbym, że to niemożliwe, po prostu nie proste.

Zbudowałem coś takiego i tak, to nie jest idealne, ale pierwszy krok jest niezbędny: sprawdzić, czy jest jakaś łączność sieciowa. Interfejs API systemu Windows nie wykonuje dobrej roboty, więc dlaczego nie zrobić lepszej pracy?

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

Jest to dość proste, ale naprawdę pomaga poprawić jakość kontroli, szczególnie gdy chcesz sprawdzić różne konfiguracje proxy.

Więc:

  • Sprawdź, czy istnieje łączność sieciowa (zrób to naprawdę dobrze, może nawet wysyłaj dzienniki do programistów, gdy istnieją fałszywe alarmy, aby poprawić funkcję NetworkIsAvailable)
  • Ping HTTP
  • (Przełączaj konfiguracje proxy z pingami HTTP na każdym)
Todd
źródło
1
@hackerman to nieoczywisty pierwszy krok. Kodery mogą opracować szybki ping do własnego serwera, jeśli zwróci on wartość true, jako drugi krok. Co ważne, stanowi to alternatywę dla wadliwej metody API systemu Windows. Reszta to szczegóły.
Todd
3
Fałszować. Jeśli nie ma interfejsu sieciowego, zdecydowanie nie ma internetu. Interfejs użytkownika można natychmiast zaktualizować bez opóźnień, bez dalszych kontroli innych hostów.
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
źródło
Proszę skomentować swoją odpowiedź. Odpowiedzi zawierające tylko kod są niedozwolone.
ganchito55
To całkiem oczywiste, że policja ma na celu zachowanie policji?
rzuca
0

Użyj NetworkMonitor do monitorowania stanu sieci i połączenia internetowego.

Próba:

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

źródło
Fajny pomysł, ale sprawdza dostępność sieci, a nie dostępność Internetu
John Demetriou,
Ta klasa sprawdza również dostępność Internetu: SourceCode
Chodzi o to, że próbowałem, ale uruchomił się tylko, gdy żadna sieć nie była dostępna
John Demetriou
0

Wprowadzenie

W niektórych scenariuszach musisz sprawdzić, czy internet jest dostępny, czy nie używa kodu C # w aplikacjach Windows. Może być pobranie lub przesłanie pliku przez Internet w formularzach systemu Windows lub pobranie danych z bazy danych, która znajduje się w zdalnej lokalizacji, w takich sytuacjach sprawdzenie Internetu jest obowiązkowe.

Istnieje kilka sposobów sprawdzenia dostępności Internetu za pomocą kodu C # z tyłu kodu. Wszystkie takie sposoby są wyjaśnione tutaj, w tym ich ograniczenia.

  1. InternetGetConnectedState (wininet)

Interfejs API „wininet” może służyć do sprawdzania, czy system lokalny ma aktywne połączenie z Internetem, czy nie. Przestrzeń nazw użyta do tego to „System.Runtime.InteropServices” i zaimportuj dll „wininet.dll” za pomocą DllImport. Następnie utwórz zmienną boolowską ze statyczną zewnętrzną o nazwie funkcji InternetGetConnectedState z opisem dwóch parametrów i zastrzeżoną wartością, jak pokazano w przykładzie.

Uwaga: Modyfikator zewnętrzny służy do deklarowania metody zaimplementowanej zewnętrznie. Typowym zastosowaniem zewnętrznego modyfikatora jest atrybut DllImport, gdy używasz usług Interop do wywoływania kodu niezarządzanego. W takim przypadku metodę należy również zadeklarować jako statyczną.

Następnie utwórz metodę o nazwie „IsInternetAvailable” jako wartość logiczną. Powyższa funkcja zostanie użyta w tej metodzie, która zwraca status internetowy systemu lokalnego

[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

W poniższym przykładzie użyto metody GetIsNetworkAvailable do ustalenia, czy połączenie sieciowe jest dostępne.

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

Uwagi (zgodnie z MSDN): Połączenie sieciowe jest uważane za dostępne, jeśli jakikolwiek interfejs sieciowy jest oznaczony jako „up” i nie jest interfejsem pętli zwrotnej ani tunelowania.

Istnieje wiele przypadków, w których urządzenie lub komputer nie jest podłączone do użytecznej sieci, ale nadal jest uważane za dostępne, a GetIsNetworkAvailable zwróci wartość true. Na przykład, jeśli urządzenie z uruchomioną aplikacją jest podłączone do sieci bezprzewodowej, która wymaga serwera proxy, ale serwer proxy nie jest ustawiony, GetIsNetworkAvailable zwróci wartość true. Innym przykładem, gdy GetIsNetworkAvailable zwróci wartość true, jest aplikacja działająca na komputerze podłączonym do koncentratora lub routera, w którym koncentrator lub router utracił połączenie nadrzędne.

  1. Pinguj nazwę hosta w sieci

Klasy Ping i PingReply pozwalają aplikacji ustalić, czy komputer zdalny jest dostępny przez sieć, otrzymując odpowiedź od hosta. Te klasy są dostępne w przestrzeni nazw System.Net.NetworkInformation. Poniższy przykład pokazuje, jak wysłać polecenie ping do hosta.

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

Uwagi (zgodnie z MSDN): Aplikacje używają klasy Ping do wykrywania, czy komputer zdalny jest osiągalny. Topologia sieci może określić, czy Ping może pomyślnie skontaktować się ze zdalnym hostem. Obecność i konfiguracja serwerów proxy, sprzętu do translacji adresów sieciowych (NAT) lub zapór ogniowych może uniemożliwić działanie Pinga. Pomyślny ping wskazuje tylko, że zdalny host jest dostępny w sieci; obecność usług wyższego poziomu (takich jak serwer WWW) na zdalnym hoście nie jest gwarantowana.

Komentarze / sugestie są zaproszone. Miłego kodowania ......!

Khuram Shahzad
źródło
-1

W przypadku mojej aplikacji testujemy również, pobierając niewielki plik.

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

Również. Niektórzy usługodawcy internetowi mogą używać środkowego serwera do buforowania pliku. Dodaj losowy nieużywany parametr np. https://www.microsoft.com/favicon.ico?req=random_number Może zapobiec buforowaniu.

użytkownik 282341
źródło
-1

Mam problem z tą metodą na moim routerze / modemie 3g, ponieważ jeśli Internet jest odłączony, router przekierowuje stronę na stronę z odpowiedzią, więc nadal dostajesz parę i twój kod myśli, że jest internet. Jabłka (lub inne) mają stronę dedykowaną, która zawsze zwraca określoną odpowiedź. Poniższy przykład zwraca odpowiedź „Sukces”. Dzięki temu będziesz mieć pewność, że możesz połączyć się z Internetem i uzyskać prawdziwą odpowiedź!

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
źródło
-2

Mam trzy testy połączenia z Internetem.

  • Odniesienie System.NetiSystem.Net.Sockets
  • Dodaj następujące funkcje testowe:

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

Przeprowadzanie testów

Jeśli się Dictionaryz Stringi Booleannazywa CheckList, można dodać wyniki testu dla każdego CheckList.

Teraz przejrzyj każdą KeyValuePairz nich za pomocą for...eachpętli.

Jeśli CheckListzawiera Valueod true, wtedy wiesz, że istnieje połączenie z Internetem.

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

To działa

slayerIQ
źródło
46
Jeśli masz adres IP Google'a w pamięci podręcznej DNS, nie wyśle ​​on żądania DNS, więc może zwrócić wartość true, nawet jeśli nie masz połączenia
Thomas Levesque