Подтвердить что ты не робот

Как определить работу интернет-соединения в С#?

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

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

4b9b3361

Ответ 1

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

System.Net.NetworkInformation.NetworkInterface.GetIsNetworkAvailable()

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

Из MSDN: Сетевое соединение считается доступным, если какой-либо сетевой интерфейс помечен как "вверх" и не является интерфейсом loopback или туннеля.

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

Ответ 2

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

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

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

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

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

Ответ 3

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

using System.Net.NetworkInformation;

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

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

Ответ 4

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

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

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

Изменить в ответ на комментарии Джейсона

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

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

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

Ответ 6

Если вам сложно выполнить ping, просто используйте webclient.

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

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

Ответ 7

просто написал async-функции для этого:

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