Определить, доступно ли подключение к интернету - PullRequest
12 голосов
/ 07 декабря 2009

Я знаю, что я не первый, кто задает вопрос: как мне узнать, находится ли мое приложение в сети или нет? Я нашел этот пост: StackOverflow . Я хочу сделать это с C # и .NET 3.5.

Рекомендуется регулярно проверять ресурс. Я не очень доволен этим советом. Я предпочел бы обнаружить изменение сети и ТОГДА пропинговать мой сервис, чтобы проверить, работает ли он онлайн.

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

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

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

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

Ответы [ 8 ]

8 голосов
/ 07 декабря 2009

Я попробовал ссылку, предложенную 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 голосов
/ 28 мая 2012

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

2 голосов
/ 07 декабря 2009

Попробуйте, используя NetworkChange class

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");
    }
}
0 голосов
/ 07 декабря 2009

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

0 голосов
/ 07 декабря 2009

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

0 голосов
/ 07 декабря 2009

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

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

РЕДАКТИРОВАТЬ: Эта статья имеет дело с событиями сетевого адреса на более низком уровне, чем класс System.Net.NetworkInformation.NetworkChange, или так кажется.На моем компьютере это работает очень быстро, так что, надеюсь, вы сможете использовать это решение.

0 голосов
/ 07 декабря 2009

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

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

0 голосов
/ 07 декабря 2009

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

...