Coder Perfect

What is the best approach to use.NET to check for Internet connectivity?

Problem

In.NET, what’s the quickest and most efficient way to check for Internet connectivity?

Asked by Mohit Deshpande

Solution #1

public static bool CheckForInternetConnection(int timeoutMs = 10000, string url = null)
{
    try
    {
        url ??= CultureInfo.InstalledUICulture switch
        {
            { Name: var n } when n.StartsWith("fa") => // Iran
                "http://www.aparat.com",
            { Name: var n } when n.StartsWith("zh") => // China
                "http://www.baidu.com",
            _ =>
                "http://www.gstatic.com/generate_204",
        };

        var request = (HttpWebRequest)WebRequest.Create(url);
        request.KeepAlive = false;
        request.Timeout = timeoutMs;
        using (var response = (HttpWebResponse)request.GetResponse())
            return true;
    }
    catch
    {
        return false;
    }
}

Answered by ChaosPandion

Solution #2

There is no reliable technique to determine whether or not there is an internet connection (I assume you mean access to the internet).

However, you can make requests for resources that are almost never unavailable, such as pinging google.com or something like. This, I believe, would be effective.

try { 
    Ping myPing = new Ping();
    String host = "google.com";
    byte[] buffer = new byte[32];
    int timeout = 1000;
    PingOptions pingOptions = new PingOptions();
    PingReply reply = myPing.Send(host, timeout, buffer, pingOptions);
    return (reply.Status == IPStatus.Success);
}
catch (Exception) {
    return false;
}

Answered by Leo

Solution #3

Instead of checking, just conduct the action (web request, mail, ftp, etc.) and be prepared for the request to fail, which you will have to do regardless of whether 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

Your activity will fail just as quickly as a ping, etc. if the network is down.

1 - start to perform action
2 - if the net is down(or goes down) the action will fail

Answered by dbasnett

Solution #4

NetworkInterface. The GetIsNetworkAvailable method is quite unreliable. All you need is a VMware or other LAN connection to get an incorrect result. Also, there’s Dns. I was just concerned about the GetHostEntry method since I was worried that the test URL would be restricted in the environment where my application would be deployed.

Another solution I discovered is to use the InternetGetConnectedState function. My code is as follows:

[System.Runtime.InteropServices.DllImport("wininet.dll")]
private extern static bool InternetGetConnectedState(out int Description, int ReservedValue);

public static bool CheckNet()
{
     int desc;
     return InternetGetConnectedState(out desc, 0);         
}

Answered by Kamran Shahid

Solution #5

When you ping google.com, you create a DNS resolution dependency. Pinging 8.8.8.8 works fine, however Google is a long way away. All I have to do is ping the closest thing on the internet to me.

I can use Ping’s TTL function to ping hop #1, then hop #2, and so on until I get a response from a node with a routable address; if that node has a routable address, it is connected to the internet. Hop #1 will be our local gateway/router for the majority of us, and hop #2 will be the first point on the opposite side of our fiber connection or whatever.

Because it pings whatever is closest to me on the internet, this code works for me and responds faster than some of the other solutions in this discussion.


using System.Diagnostics;
using System.Net;
using System.Net.NetworkInformation;
using System.Net.Sockets;
using System.Threading.Tasks;

public static async Task<bool> IsConnectedToInternetAsync()
{
    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++)
    {
        var options = new PingOptions(ttl, true);
        byte[] buffer = new byte[32];
        PingReply reply;
        try
        {
            using (var pinger = new Ping())
            {
                reply = await pinger.SendPingAsync(someFarAwayIpAddress, 10000, buffer, options);
            }
        }
        catch (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;
        }

        string address = reply.Address?.ToString() ?? null;
        Debug.Print($"Hop #{ttl} is {address}, {reply.Status}");

        if (reply.Status != IPStatus.TtlExpired && reply.Status != IPStatus.Success)
        {
            Debug.Print($"Hop #{ttl} is {reply.Status}, hence we are not connected.");
            return false;
        }

        if (IsRoutableAddress(reply.Address))
        {
            Debug.Print("That's routable, so we 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;
        }
    }
}

Answered by Jinlye

Post is based on https://stackoverflow.com/questions/2031824/what-is-the-best-way-to-check-for-internet-connectivity-using-net