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

后端 未结 27 2326
感动是毒
感动是毒 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: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;
            }
        }
    }
    

提交回复
热议问题