Как обнаружить работающее интернет-соединение в C #? - PullRequest
28 голосов
/ 26 марта 2010

У меня есть код C #, который в основном загружает файл по протоколу FTP (используя FtpWebRequest). Однако я хотел бы сначала определить, есть ли работающее подключение к Интернету, прежде чем пытаться загрузить файл (поскольку, если нет необходимости, нет смысла пытаться, программное обеспечение должно просто поспать некоторое время и проверить снова) .

Есть ли простой способ сделать это, или я должен просто попытаться загрузить файл, а в случае сбоя просто попробуйте еще раз, предполагая, что сетевое соединение было разорвано?

Ответы [ 7 ]

32 голосов
/ 30 сентября 2011

Просто используйте обычную функцию

System.Net.NetworkInformation.NetworkInterface.GetIsNetworkAvailable()

, которые возвращают true или false, если соединение установлено.

От MSDN: Сетевое соединение считается доступным, если какой-либо сетевой интерфейс помечен как «вверх» и не является петлевым или туннельным интерфейсом.

Имейте в виду, что подключение - это еще не все, вы можете подключиться к локальной сети, а маршрутизатор, например, не подключен к Интернету. Чтобы действительно знать, если вы подключены к Интернету, попробуйте класс Ping .

14 голосов
/ 26 марта 2010

Существует событие «изменена доступность сети», которое срабатывает, когда состояние «up» сетевого подключения изменяется на интерфейсе, который не является туннелем или шлейфом.

Вы можете прочитать состояние всех сетевых адаптеров в системе при запуске, сохранить текущее значение «сеть доступна», затем прослушать это событие и изменить переменную состояния сети при возникновении этого события. Это также похоже на то, что оно будет обрабатывать подключения удаленного доступа и ISDN.

Конечно, следует учитывать и другие факторы, например, сетевая карта подключена к маршрутизатору (и работает), но подключение к Интернету на маршрутизаторе отключено или удаленный хост не отвечает, но это по крайней мере предотвратит Вы пытаетесь установить соединение, которое не будет работать, если нет начального сетевого соединения (например, соединение VPN или ISDN не работает).

Это консольное приложение C # - запустите его, затем отключите или отключите сетевое соединение: -)

class Program
{
    static bool networkIsAvailable = false;

    static void Main(string[] args)
    {
        NetworkInterface[] nics = NetworkInterface.GetAllNetworkInterfaces();

        foreach (NetworkInterface nic in nics)
        {
            if (
                (nic.NetworkInterfaceType != NetworkInterfaceType.Loopback && nic.NetworkInterfaceType != NetworkInterfaceType.Tunnel) &&
                nic.OperationalStatus == OperationalStatus.Up)
            {
                networkIsAvailable = true;
            }
        }

        Console.Write("Network availability: ");
        Console.WriteLine(networkIsAvailable);

        NetworkChange.NetworkAvailabilityChanged += new NetworkAvailabilityChangedEventHandler(NetworkChange_NetworkAvailabilityChanged);

        Console.ReadLine();
    }

    static void NetworkChange_NetworkAvailabilityChanged(object sender, NetworkAvailabilityEventArgs e)
    {
        networkIsAvailable = e.IsAvailable;

        Console.Write("Network availability: ");
        Console.WriteLine(networkIsAvailable);
    }
}
12 голосов
/ 26 марта 2010

Я думаю, что лучшее приближение , которое вы можете использовать, это проверить значение OperationalStatus для типа NetworkInterface.

using System.Net.NetworkInformation;

public bool IsNetworkLikelyAvailable() {
  return NetworkInterface
    .GetAllNetworkInterfaces()
    .Any(x => x.OperationalStatus == OperationalStatus.Up);
}

Помните, хотя это приближение. В тот момент, когда этот метод возвращает, компьютер может потерять или получить подключение к Интернету. IMO Я бы просто пошел на загрузку и обработал ошибку, так как вы не можете доказать, что это не произойдет.

6 голосов
/ 26 марта 2010

Разве вы не можете просто использовать класс Ping пространства имен System.Net.NetworkInformation для проверки связи с сервером FTP перед попыткой загрузить файл?

6 голосов
/ 26 марта 2010

Подумайте о ситуации, когда ваш чек возвращается и говорит «соединение есть», и, прежде чем вы сможете запустить свой FTP, соединение обрывается.

Или когда соединение прерывается частично через ваш запрос FTP.

Учитывая, что вы все равно должны кодировать для этих ситуаций , просто пропустите проверку

Редактировать в ответ на комментарии Джейсона

Вы также можете столкнуться с противоположным состоянием - когда вы проверяете соединение, ничего не существует, но через мгновение их соединение возникает.Итак, что вы делаете - вы начинаете раздражать пользователя отсутствием соединения, даже если оно теперь доступно?

В конце концов, вы имеете дело с большим количеством ресурсов (ваше сетевое соединение, любые промежуточные маршрутизаторы, хост, его FTP-сервис).Все они могут быть изменены вне вашего контроля (как указано в комментарии Сета), и никакое предварительное тестирование не ответит на вопрос «смогу ли я завершить эту загрузку»?

Как указано в ОПчто он думает о подходе «отойди и попробуй позже», тогда я думаю, что это уместно делать все это в фоновом режиме и вообще не раздражать пользователя - если вы не пытались «неоправданно» много временибез успеха.

5 голосов
/ 24 января 2014

, если вам сложно пинговать, просто используйте веб-клиент.

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

или любой другой сайт. РЕДАКТИРОВАТЬ: вы можете использовать http://www.msftncsi.com/ этот сайт. Это сайт, который работает только для подключения к интернету. См. Подробное описание реестра о том, как Windows 7 находит подключение к Интернету http://blog.superuser.com/2011/05/16/windows-7-network-awareness/

1 голос
/ 15 февраля 2014

только что написал асинхронные функции для этого:

    private void myPingCompletedCallback(object sender, PingCompletedEventArgs e)
    {
        if (e.Cancelled)
            return;

        if (e.Error != null)
            return;

        if (e.Reply.Status == IPStatus.Success)
        {
            //ok connected to internet, do something...
        }
    }

    private void checkInternet()
    {
        Ping myPing = new Ping();
        myPing.PingCompleted += new PingCompletedEventHandler(myPingCompletedCallback);
        try
        {
            myPing.SendAsync("google.com", 3000 /*3 secs timeout*/, new byte[32], new PingOptions(64, true));
        }
        catch
        {
        }
    }
...