Який найкращий спосіб перевірити наявність підключення до Інтернету за допомогою .NET?


237

Який найшвидший і найефективніший спосіб перевірити наявність підключення до Інтернету в .NET?


6
Якщо у користувача є Інтернет-взаємодію. Якщо користувач може підключитися до Інтернету. Для того, щоб надіслати журнал електронної пошти.
Мохіт Дешпанде

11
Просто надішліть електронний лист. Якщо користувач не підключений, ви, ймовірно, отримаєте якийсь виняток (з яким, напевно, вам доведеться все-таки впоратися).
Сет

15
Крім того , зверніть увагу , що немає ніякого способу , щоб перевірити , якщо користувач буде підключений до Інтернету; все, що ви можете сказати, це якщо вони були пов'язані в минулому . Припустимо, у вас був метод: "bool c = IsConnected (); якщо (c) {DoSomething ();}" - між викликом до IsConnected та DoSomething, маршрутизатор бездротової мережі, можливо, був відключений. IsConnected насправді слід називати WasRecentlyConnected.
Ерік Ліпперт

Windows NLM APIмає бути найкращим для цього. stackoverflow.com/questions/5405895/…
Махбубур Рахман

Відповіді:


292

Щось подібне повинно працювати.

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

18
Це, мабуть, краще, ніж пінг Google, тому що я думаю, що ми не маємо гарантії, що Google продовжує реагувати на pings. З іншого боку, я не можу уявити світ, де www.google.com не повертає HTML-код :)
Даніель Вассалло,

3
@Daniel: правда, з одного боку, але з іншого боку, фактично завантаження веб-сайту є невеликим накладним зображенням
Лев,

9
Так чи інакше, немає причин повертати 4KB назад - просто використовуйте client.OpenRead (url) замість цього. Якщо він не кидає виняток, тоді він зміг підключитися.
Джош М.

14
Це насправді не так ефективно. Використання цього дозволяє моїй програмі запуститись понад 1 хвилину, якщо немає Інтернету. Можливо, через спробу вирішити DNS. Pinging 8.8.8.8 (google dns) змінив його на 3 секунди.
MadBoy

8
@DanielVassallo I cannot image a world where www.google.com does not return some HTMLв Китаї, наприклад ...
Jérôme MEVEL

84

Існує абсолютно ніякий спосіб, коли ви можете надійно перевірити, чи є підключення до Інтернету чи ні (я вважаю, ви маєте на увазі доступ до Інтернету).

Однак ви можете запитувати ресурси, які практично ніколи не є офлайн, як-от pinging google.com чи щось подібне. Я думаю, що це було б ефективно.

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

24
+1 "Немає можливості достовірно перевірити, чи є підключення до Інтернету"
woz

6
Все це - перевірити, чи не працює Google, коли ви його пінг. Якщо наступного моменту після вашого успішного пінг-інтернету знизиться, то що? Перед тим, як це робити, немає сенсу перевіряти.
dbasnett

12
І як це суперечить головному твердженню моєї відповіді?
Лев

10
Використання "google.com" займе більше часу, оскільки його потрібно вирішити. Натомість пінгінг безпосередньо за допомогою IP буде швидше. Пінгінг на IP-адреси ( 8.8.8.8або 8.8.4.4) загальнодоступних DNS для мене працює добре.
Мангеш

8
Я хотів би ще раз зазначити, що Beware - many schools and offices block the ping protocol.якщо ви використовуєте цей метод для програми, яка буде використовуватися клієнтами, я б радив проти цього способу перевірки Інтернету
user1

42

Замість перевірки просто виконайте дію (веб-запит, пошта, ftp тощо) і будьте готові до відмови запиту, що вам доведеться зробити в будь-якому випадку, навіть якщо перевірка пройшла успішно.

Розглянемо наступне:

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

Якщо мережа знищена, ваша дія вийде з ладу так само швидко, як пінг тощо.

1 - start to perform action
2 - if the net is down(or goes down) the action will fail

9
Правильно! Просто зробіть це - але будьте готові до всіх результатів.
Полковник Паніка

3
Враховуйте наступне: Вам потрібно щось робити, якщо мережа не працює протягом X часу (наприклад, траєкторія, скидання маршрутизатора)
Абір

2
Це не ОП, але я хочу це зробити, щоб уникнути ВІДХОДЖЕННЯ 100 ДРУГОГО ЧАСУ, якщо підключення до Інтернету недоступне. Запит HTTP виконується у фоновому потоці, тому потік інтерфейсу користувача не блокується, але моя програма не може вийти, поки фоновий потік не повернеться з HTTP-запиту та не припиниться. Замість того, щоб спробувати знайти якесь значення "щасливого середнього" таймауту, я хотів би просто уникнути запиту, якби я знав, що підключення до Інтернету не працює.
Скотт Сміт

2
Моя думка полягала в тому, що ми не можемо пояснити, коли віддалений сервіс може стати доступним / недоступним. Крім того, як щодо сайтів, які не відповідають pings?
dbasnett

Ще один випадок використання - це онлайн-перевірка, яка сповістить мене, як тільки мій Інтернет з’явиться,
Бен Філіп

28

NetworkInterface.GetIsNetworkAvailableдуже ненадійний. Просто підключіться VMware або інша локальна мережа, і це поверне неправильний результат. Також щодо Dns.GetHostEntryметоду мене просто хвилювало питання про те, чи може блокована тестова URL-адреса в середовищі, де мою програму буде розгорнута.

Отже, інший спосіб, який я дізнався, - це використання InternetGetConnectedStateметоду. Мій код є

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

Під час тестування я виявив, що InternetGetConnectedState повернув справжнє значення, коли встановлено програвач VMWare (відключений Інтернет). Довелося відключити його в Панелі керування \ Мережа та Інтернет \ Мережеві підключення (VMNet1 та VMNet8).
ХокейJ

Добре Джастін Орінгер. Хоча я перевірив це, але мушу ще раз перевірити
Камран Шахід

2
Найкращий підхід для мене, я все-таки перевіряю підключення до служби після цього, а потім запускаю підпрограми ... Я просто хотів уникати винятків.
Вагнер Бертоліні Юніор

4
Цей код перевіряє, чи підключено мережевий кабель.
HackerMan

14

Тест на підключення до Інтернету за допомогою pinging Google:

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

7
Опис для подальшої відповіді буде корисним для більшості людей, ніж просто оригінальний автор питання.
Boeckm

13
Остерігайтеся - багато шкіл та офісів блокують протокол ping. Дурне, я знаю.
Полковник Паніка

Я не можу знайти клас ping. ви можете, будь ласка, допомогти мені. Я працюю над UWP, а в іншому випадку перегляд інформації в мережі не працює
iam.Carrot

12

Я не погоджуюся з людьми, які заявляють: "Який сенс у перевірці підключення перед виконанням завдання, оскільки відразу після перевірки з'єднання може бути втрачено". Безумовно, існує багато невизначеностей у багатьох завданнях програмування, які ми, як розробники, беремо на себе, але зниження невизначеності до рівня прийняття є частиною завдання.

Нещодавно я зіткнувся з цією проблемою, роблячи додаток, який включає функцію відображення, яка пов’язана з он-лайн сервером плиток. Цю функціональність потрібно було відключити, коли відмічено відсутність підключення до Інтернету.

Деякі відповіді на цій сторінці були дуже хорошими, але, однак, викликали чимало проблем із роботою, такими як підвішування, головним чином у випадку відсутності підключення.

Ось рішення, яке я в кінцевому підсумку використав за допомогою деяких із цих відповідей та моїх колег:

         // 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

Я бачив усі перераховані вище варіанти, і єдиний життєздатний варіант перевірити, чи є в Інтернеті доступний чи ні - це варіант "Пінг". Імпорт [DllImport("Wininet.dll")]та System.Net.NetworkInformation.NetworkInterface.GetAllNetworkInterfaces() будь-яка інша зміна NetworkInterface класу не спрацьовує при виявленні доступності мережі. Ці методи перевіряють, чи підключений мережевий кабель чи ні.

"Варіант пінг"

if(З'єднання доступне) повертається true

if(З'єднання недоступне, а мережевий кабель підключено) повертається false

if(Мережевий кабель не підключено) Throws an exception

Мережевий інтерфейс

if(Інтернет доступний) Повернення True

if(Інтернет недоступний, а мережевий кабель підключений) Повертається True

if(Мережевий кабель не підключений) повертається false

[DllImport ("Wininet.dll")]

if(Інтернет доступний) Повернення True

if(Інтернет недоступний, а мережевий кабель підключений) Повертається True

if(Мережевий кабель не підключений) повертається false

Так що у випадку [DllImport("Wininet.dll")] та NetworkInterface немає способу дізнатися, чи є підключення до Інтернету.


Це неправда, я імпортував Wininet.dll, підключив мережевий кабель і отримав правильний результат, коли інтернет-сценарій не доступний.
Waldemar Gałęzinowski

8

Не вирішує проблему переходу мережі між перевіркою та запуском коду, але є досить надійною

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

Чудова ідея, але, як ви сказали, може бути не ідеальною. Ви можете кешувати відправлені / отримані байти, а також для майбутніх перевірок. Все ще не ідеально, хоча.
Тодд

Цей код не працює, будь ласка, виправте. Він перевіряє, чи підключено мережевий кабель чи ні.
HackerMan

5

Pinging google.com вводить залежність від роздільної здатності DNS. Пінгінг 8.8.8.8 - це добре, але Google на кілька хмелів від мене. Все, що мені потрібно зробити - це надіслати на мене найближчу інформацію в Інтернеті.

Я можу використовувати функцію TTL Ping для пінг-хопу №1, потім скакання №2 тощо, поки не отримаю відповідь від того, що є за адресою маршрутизації; якщо цей вузол знаходиться за адресою маршрутизації, то він є в Інтернеті. Для більшості з нас, хоп №1 буде нашим локальним шлюзом / маршрутизатором, а перехід №2 стане першою точкою на іншій стороні нашого волоконного з'єднання або будь-якого іншого.

Цей код працює для мене і реагує швидше, ніж деякі інші пропозиції в цій темі, оскільки він переносить все, що мені найближче в Інтернеті.

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

4

Ось як це реалізовано в Android.

Як доказ концепції, я переклав цей код на 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
    }
}

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

2

Інший варіант - API Network List Manager, який доступний для Vista та Windows 7. Стаття MSDN тут . У статті наведено посилання на завантаження зразків коду, які дозволяють це зробити:

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

Обов’язково додайте посилання на бібліотеку Network List 1.0 на вкладці COM ..., яка відображатиметься як NETWORKLIST.


7
eeeeww Використання COM пекла в .NET?
jgauffin

@jgauffin Чи можете ви пояснити, чому слід уникати COM у .NET? Порівняно з іншими рішеннями, які я знайшов, рішення COM, здається, працює досить добре.
невмілий

2

Спробуйте уникати тестування з'єднань, перехопивши виняток. тому що ми дійсно очікуємо, що іноді ми можемо втратити мережевий зв’язок.

 if (NetworkInterface.GetIsNetworkAvailable() &&
     new Ping().Send(new IPAddress(new byte[] { 8, 8, 8, 8 }),2000).Status == IPStatus.Success)
 //is online
 else
 //is offline

1
Звідки береться мережевий інтерфейс? EDIT: Я знаходжу це: System.Net.NetworkInformation
inspire_coding


1

Я особисто знаходжу відповідь Антона та moffeltje найкраще, але я додав чек для виключення віртуальних мереж, створених VMWare та іншими.

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

FYI з документів GetIsNetworkAvailable (): мережеве з'єднання вважається доступним, якщо будь-який мережевий інтерфейс позначений "вгору" і не є інтерфейсом із зворотним циклом чи тунелем. Я не знаю, чи віртуальний завжди буде в імені чи описі інтефейсу. Це стандарт?
Майк Чіл

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

1
Чи можете ви додати інформацію, що стосується швидкості цього, і як це краще, ніж інші розміщені рішення. Це допоможе вашій відповіді повністю вирішити питання.
Ren

8
Проблема з цим варіантом полягає в тому, bbщо все-таки буде вірно, навіть якщо мережа не підключена до Інтернету.
halfpastfour.am

2
Хоча це правда, що це не відповідає безпосередньо на запитання, я вважаю, що все-таки корисно використовувати GetIsNetworkAvailable як попередню перевірку перед спробою пінг-програми Google тощо.
Бен Хьюз

3
Цей Кодекс не говорить про те, доступно чи ні. Якщо ви підключите мережевий кабель без Інтернету, він повернеться правдою.
HackerMan

1

Багатопотокова версія 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

Я б не вважав, що це неможливо, просто не прямо.

Я створив щось подібне, і так, це не є ідеальним, але перший крок є важливим: перевірити, чи є підключення до мережі. Windows Api не робить великої роботи, то чому б не зробити кращу роботу?

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

Це досить просто, але це дійсно допомагає покращити якість перевірки, особливо коли ви хочете перевірити різні конфігурації проксі.

Так:

  • Перевірте, чи є підключення до мережі (зробіть це справді добре, можливо, навіть журнали надсилаються назад розробникам, коли є помилкові позитиви для покращення функції NetworkIsAvailable)
  • HTTP Ping
  • (Прокрутіть конфігурації проксі з HTTP-пінгами на кожній)

1
@hackerman - це не очевидний перший крок. Кодери можуть розробити швидкий пінг на своєму власному сервері, якщо він повернеться true, як другий крок. Важливо, що це дає альтернативу несправному методу api windows. Решта - деталі.
Тодд

3
Фальсифікувати. Якщо жодного мережевого інтерфейсу не встановлено, Інтернету точно немає. Інтерфейс можна оновлювати відразу без затримки, без подальших перевірок інших хостів.
Тодд

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

Будь ласка, прокоментуйте свою відповідь. Відповіді з лише кодом заборонені.
ganchito55

Це досить роз'яснення, поліція заради поліції?
булочки

0

Використовуйте NetworkMonitor для моніторингу стану мережі та підключення до Інтернету.

Зразок:

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

Хороша ідея, але перевіряємо наявність мережі, а не доступність в Інтернеті
Джон Деметріу

Цей клас також перевіряє наявність Інтернету: SourceCode

річ у тому, що я спробував це, але він запустився, лише якщо мережа не була доступна
Джон Деметріу

0

Вступ

У деяких сценаріях потрібно перевірити, чи доступний Інтернет чи не використовується код C # у програмах Windows. Це може бути завантаження або завантаження файлу за допомогою Інтернету у формах Windows або отримання деяких даних з бази даних, яка знаходиться у віддаленому місці, в цих ситуаціях перевірка в Інтернеті є обов'язковою.

Існує кілька способів перевірити наявність Інтернету за допомогою C # з коду позаду. Усі такі способи пояснюються тут, включаючи їх обмеження.

  1. InternetGetConnectedState (wininet)

API "wininet" можна використовувати для перевірки того, чи локальна система має активне підключення до Інтернету чи ні. Простір імен, використовуваний для цього, є 'System.Runtime.InteropServices' та імпортує dll 'wininet.dll' за допомогою DllImport. Після цього створіть булеву змінну з зовнішньою статикою з назвою функції InternetGetConnectedState з описом двох параметрів та зарезервованою Value, як показано в прикладі.

Примітка: зовнішній модифікатор використовується для оголошення способу, який реалізується зовні. Загальне використання модифікатора зовнішнього використання - це атрибут DllImport, коли ви використовуєте служби Interop для входу в некерований код. У цьому випадку метод також повинен бути оголошений статичним.

Далі створіть метод з ім'ям "IsInternetAvailable" як булевим. Вищевказана функція буде використовуватися в цьому методі, який повертає статус Інтернет в локальній системі

[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

У наступному прикладі використовується метод GetIsNetworkAvailable, щоб визначити, чи доступне мережеве з'єднання.

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

Зауваження (відповідно до MSDN): мережеве з'єднання вважається доступним, якщо будь-який мережевий інтерфейс позначений "вгору" і не є інтерфейсом зворотного зв'язку або тунелем.

Є багато випадків, коли пристрій або комп’ютер не підключені до корисної мережі, але все ще вважаються доступними, і GetIsNetworkAvailable повернеться правдою. Наприклад, якщо пристрій, що запускає додаток, підключено до бездротової мережі, для якої потрібен проксі, але проксі не встановлено, GetIsNetworkAvailable поверне справжнє значення. Іншим прикладом, коли GetIsNetworkAvailable повернеться правдою, є те, якщо програма запущена на комп'ютері, підключеному до концентратора або маршрутизатора, де концентратор або маршрутизатор втратили з'єднання вгору.

  1. Введення імені хоста в мережу

Класи Ping і PingReply дозволяють програмі визначати, чи доступний віддалений комп'ютер по мережі, отримуючи відповідь від хоста. Ці класи доступні в просторі імен System.Net.NetworkInformation. Наведений нижче приклад показує, як пінг-хост.

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

Зауваження (відповідно до MSDN): Програми використовують клас Ping, щоб визначити, чи доступний віддалений комп'ютер. Топологія мережі може визначити, чи Ping може успішно зв’язатися з віддаленим хостом. Наявність та конфігурація проксі-серверів, обладнання перекладу мережевих адрес (NAT) або брандмауерів можуть запобігти успіху Ping. Успішний Ping вказує лише на те, що віддалений хост можна отримати в мережі; наявність послуг вищого рівня (наприклад, веб-сервера) на віддаленому хості не гарантується.

Коментарі / пропозиції запрошуються. Щасливого кодування ......!


-1

Для моєї програми ми також перевіряємо завантаження крихітного файлу.

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

Також. Деякий провайдер може використовувати середній сервер для кешування файлів. Додайте випадковий невикористаний параметр, наприклад. https://www.microsoft.com/favicon.ico?req=random_number Може запобігти кешування.


-1

У мене виникають проблеми з цим методом на моєму 3g маршрутизаторі / модемі, тому що, якщо відключений Інтернет, маршрутизатор перенаправляє сторінку на свою сторінку відповідей, тож ви все одно отримуєте пара і ваш код думає, що є Інтернет. У яблук (або інших) є сторінка відміни «гарячої точки», яка завжди повертає певну відповідь. Наступний зразок повертає відповідь "Успіх". Тож ви будете точно впевнені, що зможете підключити Інтернет та отримати реальну відповідь!

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

-2

У мене є три тести на підключення до Інтернету.

  • Довідка System.NetтаSystem.Net.Sockets
  • Додайте наступні тестові функції:

Тест 1

public bool IsOnlineTest1()
{
    try
    {
        IPHostEntry dummy = Dns.GetHostEntry("https://www.google.com");
        return true;
    }
    catch (SocketException ex)
    {
        return false;
    }
}

Тест 2

public bool IsOnlineTest2()
{
    try
    {
        IPHostEntry dummy = Dns.GetHostEntry("https://www.google.com");
        return true;
    }
    catch (SocketException ex)
    {
        return false;
    }
}

Тест 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;
    }
}

Виконання тестів

Якщо ви зробите Dictionaryз Stringі Booleanназивається CheckList, ви можете додати результати кожного тесту на CheckList.

Тепер рекурсуйте через кожен KeyValuePairза допомогою for...eachциклу.

Якщо CheckListв ньому Valueє true, то ви знаєте, що є Інтернет.


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

Це працює


46
Якщо у кеш-пам’яті DNS у вас IP-адреса google, він не надсилатиме запит DNS, тому він може повернути істину, навіть якщо ви не підключені
Thomas Levesque
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.