Как проверить сетевое соединение?


Ответы:


153

Вы можете проверить сетевое соединение в .NET 2.0, используя GetIsNetworkAvailable():

System.Net.NetworkInformation.NetworkInterface.GetIsNetworkAvailable()

Чтобы отслеживать изменения IP-адреса или изменения доступности сети, используйте события из класса NetworkChange :

System.Net.NetworkInformation.NetworkChange.NetworkAvailabilityChanged
System.Net.NetworkInformation.NetworkChange.NetworkAddressChanged

9
Это позаботится об "ограниченной доступности"?
тофутим

Это не всегда работает в WPF. Некоторые ноутбуки возвращают ложь, а некоторые
Крилович

Это действительно работает? Я просто написал эту строку и выключил свой роутер, но все равно возвращает true!
Mushfiq

1
NetworkInterface.GetIsNetworkAvailable()был очень ненадежным в моем приложении (.NET 4.5, Windows 10), особенно при работе на виртуальной машине. Обработка событий из NetworkAvailabilityChangedбыла надежной.
eskimwier

Это ненадежно. прочитайте stackoverflow.com/a/25779403/2377343
T.Todua

174

Отмеченный ответ на 100% хорош, однако есть определенные случаи, когда стандартный метод обманывают виртуальные карты (виртуальный ящик, ...). Также часто желательно отказаться от некоторых сетевых интерфейсов в зависимости от их скорости (последовательные порты, модемы, ...).

Вот фрагмент кода, который проверяет эти случаи:

    /// <summary>
    /// Indicates whether any network connection is available
    /// Filter connections below a specified speed, as well as virtual network cards.
    /// </summary>
    /// <returns>
    ///     <c>true</c> if a network connection is available; otherwise, <c>false</c>.
    /// </returns>
    public static bool IsNetworkAvailable()
    {
        return IsNetworkAvailable(0);
    }

    /// <summary>
    /// Indicates whether any network connection is available.
    /// Filter connections below a specified speed, as well as virtual network cards.
    /// </summary>
    /// <param name="minimumSpeed">The minimum speed required. Passing 0 will not filter connection using speed.</param>
    /// <returns>
    ///     <c>true</c> if a network connection is available; otherwise, <c>false</c>.
    /// </returns>
    public static bool IsNetworkAvailable(long minimumSpeed)
    {
        if (!NetworkInterface.GetIsNetworkAvailable())
            return false;

        foreach (NetworkInterface ni in NetworkInterface.GetAllNetworkInterfaces())
        {
            // discard because of standard reasons
            if ((ni.OperationalStatus != OperationalStatus.Up) ||
                (ni.NetworkInterfaceType == NetworkInterfaceType.Loopback) ||
                (ni.NetworkInterfaceType == NetworkInterfaceType.Tunnel))
                continue;

            // this allow to filter modems, serial, etc.
            // I use 10000000 as a minimum speed for most cases
            if (ni.Speed < minimumSpeed)
                continue;

            // discard virtual cards (virtual box, virtual pc, etc.)
            if ((ni.Description.IndexOf("virtual", StringComparison.OrdinalIgnoreCase) >= 0) ||
                (ni.Name.IndexOf("virtual", StringComparison.OrdinalIgnoreCase) >= 0))
                continue;

            // discard "Microsoft Loopback Adapter", it will not show as NetworkInterfaceType.Loopback but as Ethernet Card.
            if (ni.Description.Equals("Microsoft Loopback Adapter", StringComparison.OrdinalIgnoreCase))
                continue;

            return true;
        }
        return false;
    }

17
это правильно и заслуживает множества положительных отзывов - я обнаружил, что событие NetworkAvailabilityChanged, упомянутое в принятом ответе, не запускается надежно, что, вероятно, вызвано виртуальными адаптерами, упомянутыми в этом ответе,
Марек

1
+1 за дополнительную проверку виртуальных машин. Просто столкнулся с этим делом вчера. Но я все еще думаю, что это не относится к «Hype-V», потому что в их имени нет «виртуального».
Herdo

3
@Herdo - да, код не идеален, и я не думаю , что в виртуальном мире может быть что-то идеальное. Но вы можете это улучшить.
Саймон Мурье

@SimonMourier. Вы правы. Просто хотел отметить, что, если кто-то по-прежнему
вернет

1
@noelicus - В проектах, над которыми я работал до сих пор, я реализовал систему периодического мониторинга / опроса (простые запросы HTTP GET, потому что я был нацелен на веб-сервер), которая вызывает события, когда сервер обнаруживается как "неработающий" (недоступный по HTTP) или «вверх» (снова достижим). В общем случае вы можете определить, что означает «надежный» в вашем случае, и реализовать аналогичную логику.
Саймон Мурье,

9

Microsoft Windows Vista и 7 используют технику NCSI (индикатор состояния сетевого подключения):

  1. NCSI выполняет поиск в DNS на сайте www.msftncsi.com, затем запрашивает http://www.msftncsi.com/ncsi.txt . Этот файл представляет собой обычный текстовый файл и содержит только текст « Microsoft NCSI ».
  2. NCSI отправляет запрос поиска DNS для dns.msftncsi.com. Этот DNS-адрес должен разрешаться в 131.107.255.255. Если адрес не совпадает, предполагается, что подключение к Интернету работает неправильно.

3
Это здорово, но технически не о доступности «сети», а скорее о том, «есть ли у меня подключение к Интернету через http?» У вас может быть идеальное сетевое соединение, но нет подключения к Интернету, например, в автономной локальной сети. См. Дополнительную информацию о NCSI: technet.microsoft.com/en-us/library/cc766017.aspx
MichielB

1

Вызовите этот метод, чтобы проверить сетевое соединение.

public static bool IsConnectedToInternet()
        {
            bool returnValue = false;
            try
            {

                int Desc;
                returnValue = Utility.InternetGetConnectedState(out Desc, 0);
            }
            catch
            {
                returnValue = false;
            }
            return returnValue;
        }

Поместите эту строку кода ниже.

[DllImport("wininet.dll")]
        public extern static bool InternetGetConnectedState(out int Description, int ReservedValue);
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.