What is the best way to check for Internet connectivity using .NET?

后端 未结 27 2046
感动是毒
感动是毒 2020-11-22 07:41

What is the fastest and most efficient way to check for Internet connectivity in .NET?

相关标签:
27条回答
  • 2020-11-22 08:37
    private bool ping()
    {
        System.Net.NetworkInformation.Ping pingSender = new System.Net.NetworkInformation.Ping();
        System.Net.NetworkInformation.PingReply reply = pingSender.Send(address);
        if (reply.Status == System.Net.NetworkInformation.IPStatus.Success)
        {                
            return true;
        }
        else
        {                
            return false;
        }
    }
    
    0 讨论(0)
  • 2020-11-22 08:40

    Instead of checking, just perform the action (web request, mail, ftp, etc.) and be prepared for the request to fail, which you have to do anyway, even if your check was successful.

    Consider the following:

    1 - check, and it is OK
    2 - start to perform action 
    3 - network goes down
    4 - action fails
    5 - lot of good your check did
    

    If the network is down your action will fail just as rapidly as a ping, etc.

    1 - start to perform action
    2 - if the net is down(or goes down) the action will fail
    
    0 讨论(0)
  • 2020-11-22 08:40

    I disagree with people who are stating: "What's the point in checking for connectivity before performing a task, as immediately after the check the connection may be lost". Surely there is a degree of uncertainty in many programming tasks we as developers undertake, but reducing the uncertainty to a level of acceptance is part of the challenge.

    I recently ran into this problem making an application which including a mapping feature which linked to an on-line tile server. This functionality was to be disabled where a lack of internet connectivity was noted.

    Some of the responses on this page were very good, but did however cause a lot of performance issues such as hanging, mainly in the case of the absence of connectivity.

    Here is the solution that I ended up using, with the help of some of these answers and my colleagues:

             // Insert this where check is required, in my case program start
             ThreadPool.QueueUserWorkItem(CheckInternetConnectivity);
        }
    
        void CheckInternetConnectivity(object state)
        {
            if (System.Net.NetworkInformation.NetworkInterface.GetIsNetworkAvailable())
            {
                using (WebClient webClient = new WebClient())
                {
                    webClient.CachePolicy = new System.Net.Cache.RequestCachePolicy(System.Net.Cache.RequestCacheLevel.BypassCache);
                    webClient.Proxy = null;
                    webClient.OpenReadCompleted += webClient_OpenReadCompleted;
                    webClient.OpenReadAsync(new Uri("<url of choice here>"));
                }
            }
        }
    
        volatile bool internetAvailable = false; // boolean used elsewhere in code
    
        void webClient_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e)
        {
            if (e.Error == null)
            {
                internetAvailable = true;
                Dispatcher.Invoke(DispatcherPriority.Normal, new Action(() =>
                {
                    // UI changes made here
                }));
            }
        }
    
    0 讨论(0)
  • 2020-11-22 08:40

    Does not solve the problem of network going down between checking and running your code but is fairly reliable

    public static bool IsAvailableNetworkActive()
    {
        // only recognizes changes related to Internet adapters
        if (System.Net.NetworkInformation.NetworkInterface.GetIsNetworkAvailable())
        {
            // however, this will include all adapters -- filter by opstatus and activity
            NetworkInterface[] interfaces = System.Net.NetworkInformation.NetworkInterface.GetAllNetworkInterfaces();
            return (from face in interfaces
                    where face.OperationalStatus == OperationalStatus.Up
                    where (face.NetworkInterfaceType != NetworkInterfaceType.Tunnel) && (face.NetworkInterfaceType != NetworkInterfaceType.Loopback)
                    select face.GetIPv4Statistics()).Any(statistics => (statistics.BytesReceived > 0) && (statistics.BytesSent > 0));
        }
    
        return false;
    }
    
    0 讨论(0)
  • 2020-11-22 08:41

    Pinging google.com introduces a DNS resolution dependency. Pinging 8.8.8.8 is fine but Google is several hops away from me. All I need to do is to ping the nearest thing to me that is on the internet.

    I can use Ping's TTL feature to ping hop #1, then hop #2, etc, until I get a reply from something that is on a routable address; if that node is on a routable address then it is on the internet. For most of us, hop #1 will be our local gateway/router, and hop #2 will be the first point on the other side of our fibre connection or whatever.

    This code works for me, and responds quicker than some of the other suggestions in this thread because it is pinging whatever is nearest to me on the internet.

    using System.Net;
    using System.Net.Sockets;
    using System.Net.NetworkInformation;
    using System.Diagnostics;
    
    internal static bool ConnectedToInternet()
    {
        const int maxHops = 30;
        const string someFarAwayIpAddress = "8.8.8.8";
    
        // Keep pinging further along the line from here to google 
        // until we find a response that is from a routable address
        for (int ttl = 1; ttl <= maxHops; ttl++)
        {
            Ping pinger = new Ping();
            PingOptions options = new PingOptions(ttl, true);
            byte[] buffer = new byte[32];
            PingReply reply = null;
            try
            {
                reply = pinger.Send(someFarAwayIpAddress, 10000, buffer, options);
            }
            catch (System.Net.NetworkInformation.PingException pingex)
            {
                Debug.Print("Ping exception (probably due to no network connection or recent change in network conditions), hence not connected to internet. Message: " + pingex.Message);
                return false;
            }
    
            System.Diagnostics.Debug.Print("Hop #" + ttl.ToString() + " is " + (reply.Address == null ? "null" : reply.Address.ToString()) + ", " + reply.Status.ToString());
    
            if (reply.Status != IPStatus.TtlExpired && reply.Status != IPStatus.Success)
            {
                Debug.Print("Hop #" + ttl.ToString() + " is " + reply.Status.ToString() + ", hence we are not connected.");
                return false;
            }
    
            if (IsRoutableAddress(reply.Address))
            {
                System.Diagnostics.Debug.Print("That's routable so you must be connected to the internet.");
                return true;
            }
        }
    
        return false;
    }
    
    private static bool IsRoutableAddress(IPAddress addr)
    {
        if (addr == null)
        {
            return false;
        }
        else if (addr.AddressFamily == AddressFamily.InterNetworkV6)
        {
            return !addr.IsIPv6LinkLocal && !addr.IsIPv6SiteLocal;
        }
        else // IPv4
        {
            byte[] bytes = addr.GetAddressBytes();
            if (bytes[0] == 10)
            {   // Class A network
                return false;
            }
            else if (bytes[0] == 172 && bytes[1] >= 16 && bytes[1] <= 31)
            {   // Class B network
                return false;
            }
            else if (bytes[0] == 192 && bytes[1] == 168)
            {   // Class C network
                return false;
            }
            else
            {   // None of the above, so must be routable
                return true;
            }
        }
    }
    
    0 讨论(0)
  • 2020-11-22 08:41

    I have three tests for an Internet connection.

    • Reference System.Net and System.Net.Sockets
    • Add the following test functions:

    Test 1

    public bool IsOnlineTest1()
    {
        try
        {
            IPHostEntry dummy = Dns.GetHostEntry("https://www.google.com");
            return true;
        }
        catch (SocketException ex)
        {
            return false;
        }
    }
    

    Test 2

    public bool IsOnlineTest2()
    {
        try
        {
            IPHostEntry dummy = Dns.GetHostEntry("https://www.google.com");
            return true;
        }
        catch (SocketException ex)
        {
            return false;
        }
    }
    

    Test 3

    public bool IsOnlineTest3()
    {
        System.Net.WebRequest req = System.Net.WebRequest.Create("https://www.google.com");
        System.Net.WebResponse resp = default(System.Net.WebResponse);
        try
        {
            resp = req.GetResponse();
            resp.Close();
            req = null;
            return true;
        }
        catch (Exception ex)
        {
            req = null;
            return false;
        }
    }
    

    Performing the tests

    If you make a Dictionary of String and Boolean called CheckList, you can add the results of each test to CheckList.

    Now, recurse through each KeyValuePair using a for...each loop.

    If CheckList contains a Value of true, then you know there is an Internet connection.

    0 讨论(0)
提交回复
热议问题