Каков наилучший способ проверить подключение к Интернету с помощью .NET?

Каков самый быстрый и эффективный способ проверить подключение к Интернету в .NET?

Ответ 1

Нечто подобное должно работать.

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

Ответ 2

Вы абсолютно не можете надежно проверить, есть ли подключение к Интернету или нет (я предполагаю, что вы имеете в виду доступ к Интернету).

Однако вы можете запросить ресурсы, которые практически никогда не работают в автономном режиме, например, 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;
}

Ответ 3

Вместо проверки просто выполните действие (веб-запрос, почту, 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

Если сеть не работает, ваше действие завершится так же быстро, как и ping и т.д.

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

Ответ 4

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

Ответ 5

Тест для подключения к Интернету путем проверки Google:

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

Ответ 6

Я не согласен с людьми, которые заявляют: "Какой смысл в проверке подключения перед выполнением задачи, как сразу после проверки, соединение может быть потеряно". Разумеется, во многих задачах программирования мы, как разработчики, проявляем определенную неопределенность, но снижение неопределенности до уровня принятия является частью проблемы.

Недавно я столкнулся с этой проблемой, создав приложение, включающее функцию сопоставления, связанную с сервером онлайновой черепицы. Эта функция должна была быть отключена, когда было отмечено отсутствие подключения к Интернету.

Некоторые ответы на этой странице были очень хорошими, но, тем не менее, вызывали множество проблем с производительностью, таких как зависание, в основном в случае отсутствия подключения.

Вот решение, которое я использовал с помощью некоторых из этих ответов и моих коллег:

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

Ответ 7

Я видел все варианты, перечисленные выше, и единственная жизнеспособная опция проверки увядания интернета или нет - это опция "Пинг". Импорт [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 Нет способа узнать, доступно ли подключение к Интернету.

Ответ 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;
}

Ответ 9

Pinging google.com вводит зависимость разрешения DNS. Pinging 8.8.8.8 в порядке, но Google в нескольких прыжках от меня. Все, что мне нужно сделать, - это рассказать о ближайшей вещи, которая есть в Интернете.

Я могу использовать функцию Ping TTL для ping hop # 1, then hop # 2 и т.д., пока не получаю ответ от чего-то, что находится на маршрутизируемом адресе; если этот node находится на маршрутизируемом адресе, то он находится в Интернете. Для большинства из нас, хоп # 1 будет нашим локальным шлюзом/маршрутизатором, а hop # 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 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;
        }
    }
}

Ответ 10

Вот как это реализовано в Android.

В качестве доказательства концепции я перевел этот код на С#:

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

Ответ 11

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

Ответ 12

Другим вариантом является API-интерфейс диспетчера сетевых списков, который доступен для Vista и Windows 7. Статья MSDN здесь. В статье приведена ссылка для загрузки образцов кода, которые позволяют вам сделать это:

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

Обязательно добавьте ссылку на библиотеку типов List List 1.0 со вкладки COM..., которая будет отображаться как NETWORKLIST.

Ответ 14

Я лично нашел ответ Anton и 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));
}

Ответ 15

Многопоточная версия 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";
          }
      }
  }

Ответ 16

bool bb = System.Net.NetworkInformation.NetworkInterface.GetIsNetworkAvailable();

if (bb == true)
    MessageBox.Show("Internet connections are available");
else
    MessageBox.Show("Internet connections are not available");

Ответ 17

Я бы не подумал, что это невозможно, просто не просто.

Я построил что-то вроде этого, и да, это не идеально, но первый шаг необходим: проверить, есть ли какая-либо сетевая связь. 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-сообщениями на каждом)

Ответ 18

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

Ответ 19

Используйте 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");
        }
    }
}

Ответ 20

Попробуйте это:

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

Ответ 21

Для моего приложения мы также проверяем загрузку миниатюрного файла.

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 Может предотвратить кеширование.

Ответ 22

У меня возникает проблема с этим методом на моем маршрутизаторе/модемом 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;
}

Ответ 23

У меня есть три теста для подключения к Интернету.

  • Ссылка 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 содержит a Value of true, то вы знаете, что есть интернет-соединение.

Ответ 24

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

Это работает