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

Определите доступность интернет-соединения

Я знаю, что я не первый, кто задал вопрос: как узнать, подключено ли мое приложение или нет? Я нашел этот пост: qaru.site/info/423666/.... Я хочу сделать это с помощью С# и .NET 3.5.

Рекомендация - регулярно проверять ресурсы. Я не очень доволен этим советом. Я бы скорее обнаружил изменение сети, а THEN выполнил мой сервис, чтобы проверить, находится ли он в сети.

.NET предоставляет для этой цели два события: NetworkChange.NetworkAvailabilityChanged NetworkChange.NetworkAddressChanged

Первое событие звучит неплохо, но оно запускается только в том случае, если последняя сетевая карта, находящаяся в сети, отключена. У меня есть несколько виртуальных сетевых карт, которые были установлены VMWare, и они всегда в сети. Второе событие работает, но между подключением сетевого кабеля и событием часто бывает 5 секунд ожидания. Значок панели Windows реагирует более или менее немедленно, когда я отсоединяю кабель. Каков наилучший способ быть таким же быстрым, как этот значок в трее?

Моим обходным решением будет опрос NetworkInterface.GetAllNetworkInterfaces() каждые 500 мс и передать свое собственное событие в случае изменения статуса сетевого адаптера.

Должно быть лучшее решение:)

4b9b3361

Ответ 1

Я попробовал ссылку, предложенную Webleeuw, но для этого кода также требуется от 4 до 10 секунд, чтобы уведомить меня, когда я подключаю или отсоединяю кабель. Теперь я хотел знать, был ли это только мой компьютер или установка, и я написал свой собственный класс Observer, который основан на NetworkInterface.GetAllNetworkInterfaces().

И: Он работает с молниеносной скоростью. Мое приложение реагирует так же быстро, как и лоток. Код далеко от производственного кода, это просто быстрый взлом. Но вот что я буду строить сейчас:)

using System;
using System.Net.NetworkInformation;
using Timer=System.Threading.Timer;

namespace NetworkCheckApp
{
public class NetworkStatusObserver
{
    public event EventHandler<EventArgs> NetworkChanged;

    private NetworkInterface[] oldInterfaces;
    private Timer timer;

    public void Start()
    {
        timer = new Timer(UpdateNetworkStatus, null, new TimeSpan(0, 0, 0, 0, 500), new TimeSpan(0, 0, 0, 0, 500));

        oldInterfaces = NetworkInterface.GetAllNetworkInterfaces();
    }

    private void UpdateNetworkStatus(object o)
    {
        var newInterfaces = NetworkInterface.GetAllNetworkInterfaces();
        bool hasChanges = false;
        if (newInterfaces.Length != oldInterfaces.Length)
        {
            hasChanges = true;
        }
        if (!hasChanges)
        {
            for (int i = 0; i < oldInterfaces.Length; i++)
            {
                if (oldInterfaces[i].Name != newInterfaces[i].Name || oldInterfaces[i].OperationalStatus != newInterfaces[i].OperationalStatus)
                {
                    hasChanges = true;
                    break;
                }
            }
        }

        oldInterfaces = newInterfaces;

        if (hasChanges)
        {
            RaiseNetworkChanged();
        }
    }

    private void RaiseNetworkChanged()
    {
        if (NetworkChanged != null)
        {
            NetworkChanged.Invoke(this, null);
        }
    }
}
}

Ответ 2

Попробуйте это с помощью класса NetworkChange

using System.Net.NetworkInformation

private void Form5_Load(object sender, EventArgs e)
{
    NetworkChange.NetworkAvailabilityChanged += new NetworkAvailabilityChangedEventHandler(NetworkChange_NetworkAvailabilityChanged);
}

private void NetworkChange_NetworkAvailabilityChanged(object sender, NetworkAvailabilityEventArgs e)
{
    if (e.IsAvailable)
    {
        MessageBox.Show("Available");
    }
    else
    {
        MessageBox.Show("Not available");
    }
}

Ответ 3

Люди здесь уже говорили об этом, но есть разница между доступностью сети и доступностью Интернета.
Вы можете иметь доступность сети между вашим сетевым интерфейсом и локальным маршрутизатором, но не имеете доступ к интернету между вашим локальным маршрутизатором и вашим интернет-провайдером (ISP).
Другая проблема заключается в том, что тестирование ping скажет вам о доступности интернета, но не о том, какой сетевой интерфейс предоставляет его, я думаю, что единственный способ - это принудительное пинг через один интерфейс, но это невозможно в окнах.

Ответ 4

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

Ответ 5

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

Поскольку сетевая карта является лишь одной из многих ссылок между вашим клиентом и службой, к которой он обращается в Интернете, единственный надежный способ определить, доступен ли Интернет, - это опрос некоторых услуг в Интернете, много так же, как и ping. В сети TCP/IP это известно как keepalive, и многие протоколы будут встроены в них как опция.

Ответ 6

О пинге: в зависимости от того, как вы хотите интерпретировать результаты, пинг не кажется мне водонепроницаемым. Что, если цель истекает время от времени, пока соединение остается в живых? Я еще не видел сервер, который никогда не отвечает на пинг.

Проверка каждого X миллиса, если сетевой интерфейс все еще находится в сети (свойство NetworkInterface.OperationalStatus), кажется более надежным, если вы спросите меня.

EDIT: В этой статье обсуждаются события сетевого адреса на более низком уровне, чем класс System.Net.NetworkInformation.NetworkChange, или так кажется. На моем компьютере это работает очень быстро, поэтому, надеюсь, вы сможете использовать это решение.

Ответ 7

Вы можете использовать ping, но я бы также создал простой вызов, чтобы вернуть "да", если он находится в сети. Таким образом, вы знаете, работает ли сервер и что он запускает ваш код. Также я бы звонил или пинги, когда нужен сетевой ресурс, а не постоянно.

Ответ 8

Выполнение пинга определенно не самый чистый вариант, особенно если это веб-сервер. Некоторые хосты отключат ответ на трафик ICMP, поэтому вы можете выполнить ping, но не получить ответ. Как правильно обрабатывать исключение, когда оно происходит?