Jak sprawdzić połączenie sieciowe?

Odpowiedzi:

153

Możesz sprawdzić połączenie sieciowe w .NET 2.0 za pomocą GetIsNetworkAvailable():

System.Net.NetworkInformation.NetworkInterface.GetIsNetworkAvailable()

Aby monitorować zmiany adresu IP lub zmiany dostępności sieci, użyj zdarzeń z klasy NetworkChange :

System.Net.NetworkInformation.NetworkChange.NetworkAvailabilityChanged
System.Net.NetworkInformation.NetworkChange.NetworkAddressChanged
Mitch Wheat
źródło
9
Czy to eliminuje „ograniczoną dostępność”?
tofutim
To nie zawsze działa w WPF. Niektóre laptopy zwracają fałszywe, a inne zwracają prawdę
krilovich
Czy to naprawdę działa? Właśnie napisałem tę linię i wyłączam router i nadal zwraca prawdę!
Mushfiq
1
NetworkInterface.GetIsNetworkAvailable()był bardzo zawodny w mojej aplikacji (.NET 4.5, Windows 10), szczególnie podczas pracy na maszynie wirtualnej. Obsługa zdarzeń od NetworkAvailabilityChangedbyła niezawodna.
eskimwier
To nie jest wiarygodne. przeczytaj stackoverflow.com/a/25779403/2377343
T.Todua
174

Zaznaczona odpowiedź jest w 100% w porządku, jednak zdarzają się przypadki, gdy standardowa metoda jest oszukiwana przez wirtualne karty (wirtualne pudełko, ...). Często pożądane jest również odrzucenie niektórych interfejsów sieciowych na podstawie ich szybkości (porty szeregowe, modemy, ...).

Oto fragment kodu, który sprawdza te przypadki:

    /// <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;
    }
Simon Mourier
źródło
17
jest to poprawne i zasługuje na wiele głosów - stwierdziłem, że zdarzenie NetworkAvailabilityChanged wspomniane w zaakceptowanej odpowiedzi nie jest odpalane niezawodnie, co jest prawdopodobnie spowodowane przez wirtualne adaptery, o czym wspominałem w tej odpowiedzi
Marek
1
+1 za dodatkowe sprawdzenie maszyn wirtualnych. Po prostu wczoraj wpadłem na tę sprawę. Ale nadal uważam, że to nie obsługuje „Hype-V”, ponieważ nie mają w nazwie słowa „wirtualny”.
Herdo
3
@Herdo - tak, kod nie jest doskonały i nie sądzę, że może być coś doskonałego w wirtualnym świecie. Ale możesz to poprawić.
Simon Mourier,
@SimonMourier Masz rację. Chciałem tylko zauważyć, że jeśli komuś nadal zostanie zwrócona prawda, jeśli nie ma połączenia -> To może być problem :)
Herdo
1
@noelicus - W projektach, nad którymi do tej pory pracowałem, zaimplementowałem system okresowego monitorowania / odpytywania (proste żądania HTTP GET, ponieważ celowałem w serwer WWW), który wywołuje zdarzenia, gdy serwer jest wykrywany jako „wyłączony” (nieosiągalny przez HTTP) lub „w górę” (ponownie osiągalny). W ogólnym przypadku możesz zdefiniować, co oznacza „niezawodny” w twoim przypadku i zastosować podobną logikę.
Simon Mourier
9

Microsoft Windows Vista i 7 używają technologii NCSI (wskaźnik stanu łączności sieciowej):

  1. NCSI wyszukuje DNS pod adresem www.msftncsi.com, a następnie żąda http://www.msftncsi.com/ncsi.txt . Ten plik jest zwykłym plikiem tekstowym i zawiera tylko tekst „ Microsoft NCSI ”.
  2. NCSI wysyła żądanie wyszukiwania DNS dla dns.msftncsi.com. Ten adres DNS powinien rozwiązać 131.107.255.255. Jeśli adres się nie zgadza, zakłada się, że połączenie internetowe nie działa poprawnie.
Saleh Rahimzadeh
źródło
3
To świetnie, ale technicznie nie chodzi tu o dostępność „sieci”, ale bardziej o „czy mam połączenie internetowe przez http?”. Możesz mieć doskonałe połączenia sieciowe, ale nie masz połączenia z Internetem, na przykład w samodzielnej sieci LAN. Zobacz więcej informacji o NCSI: technet.microsoft.com/en-us/library/cc766017.aspx
MichielB
1

Wywołaj tę metodę, aby sprawdzić połączenie sieciowe.

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

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

Umieść poniższy wiersz kodu.

[DllImport("wininet.dll")]
        public extern static bool InternetGetConnectedState(out int Description, int ReservedValue);
Kumar
źródło