Як перевірити мережеве з'єднання?


Відповіді:


153

Ви можете перевірити мережеве з'єднання в .NET 2.0 за допомогою GetIsNetworkAvailable():

System.Net.NetworkInformation.NetworkInterface.GetIsNetworkAvailable()

Для контролю за зміною IP-адреси або змінами в доступності мережі використовуйте події з класу NetworkChange :

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

9
Чи це стосується "обмеженої доступності"?
tofutim

У WPF це не завжди працює. Деякі ноутбуки повертають помилкові, а деякі повертають правду
krilovich

Це справді робота? Я щойно написав цей рядок і відключив роутер і все ще повертає справжнє!
Мушфік

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
це правильно і заслуговує на багато оновлень - я виявив, що подія NetworkAvailableChanged, згадана у прийнятій відповіді, не є надійно зафіксованою, що, ймовірно, викликано віртуальними адаптерами, як згадується у цій відповіді
Marek

1
+1 для додаткової перевірки віртуальних машин. Просто вчора впадайте в цю справу Але я все ще думаю, що це не обробляє "Hype-V", оскільки вони не мають "віртуальної" у своєму імені.
Гердо

3
@Herdo - так, код не ідеальний, і я не думаю, що у віртуальному світі може бути щось ідеальне. Але ви можете вдосконалити це.
Саймон Мур’є

@SimonMourier Ви праві. Просто хотів зазначити, що якщо хтось все-таки повернеться справжнім, якщо немає зв’язку -> Це може бути проблемою :)
Гердо

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

9

Microsoft Windows Vista і 7 використовують техніку NCSI (Network Connectivity Indicator Status):

  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.