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

28

298

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

Annotation answered 9/1, 2010 at 0:48 Comment(7)
If the user has an internet conecction. If the user can connect to the internet. In order to send an email log.Annotation
Just send the email. If the user's not connected, you'll likely receive some kind of exception (which you would probably have to handle anyway).Lakesha
Also, note that there is no way to check if the user is connected to the internet; all you can tell is if they were connected in the past. Suppose you had a method: "bool c = IsConnected(); if (c) { DoSomething(); } " -- between the call to IsConnected and DoSomething, the wireless network router might have been unplugged. IsConnected really should be called WasRecentlyConnected.Sporting
Windows NLM API should be the best for this. #5406395Howdah
Without knowing your use case, it's probably prudent for you to be more concerned that firewalls aren't blocking access to servers you care about rather than the Internet in general.Predesignate
@Eric Lippert: Only theory. In a short period of time theres 99.99% likelihood that the within the next second the connection will also be availible. By using your logic, a doctor could never tell that his patient is alive, by testing his or pulse/heartbeat. The best way is to use ping or dns check method directly to the host you are interested in working.Bryannabryansk
@TomeeNS: In a world with tens of billions of computers, a thing that happens only 0.01% of the time happens thousands of times a day. The best practice is to assume that all operations can fail and design your program to handle error conditions correctly. See en.wikipedia.org/wiki/Fallacies_of_distributed_computing.Sporting
A
357

You could use this code, which should also work in Iran and China-

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;
    }
}
Adria answered 9/1, 2010 at 0:51 Comment(24)
This is probably better than pinging Google, because I think we have no guarantee that Google continues to respond to pings. On the other hand, I cannot image a world where www.google.com does not return some HTML :)Twitch
@Daniel: true on the one hand, but on the other hand, actually downloading the website is a little overhead imoGirosol
4KB is not very much overhead.Adria
Either way, no reason to pull the 4KB back - just use client.OpenRead(url) instead. If it doesn't throw an exception then it was able to connect.Guinea
This always returns true for me.. Even if i make the url "asdfasdf193287912387"Eellike
All this does is check that google is up. If the very next instant the internet goes down then what? There is no point in checking before doing. Somewhere I read a report that this kind of pointless exercise accounts for 2% of the traffic on the internet.Capitulary
That's actually not so efficient. Using that makes my program start over 1 minute if there's no internet. Probably due to trying to resolve DNS. Pinging 8.8.8.8 (google dns) changed it to 3 seconds.Flaherty
replace using statement to using (var client = new WebClient() { Proxy = null }) makes it way faster on my computer ;)Sparker
You could make this method even more fail-proof, by adding more URLS like www.facebook.com and www.twitter.com, the chance that all three are down is nihil.Edentate
Hi, when I try to use the above method, While executing 'client.OpenRead("google.com")', I am getting an error "The remote server returned an error: (502) Bad Gateway". please help me with this.Sollows
Is there an alternative website? google.com is so heavy. I wish there was some sort of website that just had a blank HTTP body in the response and was available all the time.Toscana
If you're testing for an Internet connection so that you can connect to a specific site (like your application server), then you should send your HTTP request to that site, and not Google. And yeah, outgoing PING gets blocked by some schools and businesses, so that's not a reliable method.Consuelaconsuelo
What benefits does this have compared to the System.Net.Sockets.TcpClient? I mean WebClient method takes several seconds, while TcpClient takes < 200ms. System.Net.Sockets.TcpClient client = new System.Net.Sockets.TcpClient("www.google.com", 80);Parous
This solution can be slow without TimeoutTrust
#520847Neidaneidhardt
@DanielVassallo I cannot image a world where www.google.com does not return some HTML in China for example...Flashlight
@Timothea our app checks for internet and gives an error if something is missng and there's no internet to download it. folks in our China office were inexplicably getting the message. i remoted in and found that the code in this check was returning false. going to the webpage itself on their computers eventually provided an error page, but in the app it was giving false. i didn't try adjusting the timeout. for them, we'd have to use a more local URL like baidu.comClod
Why should we trust this solution?! Maybe google server is down and doesn't make any response. Is there any other trusted solution independent of other websites or servers?Fullmer
is there any way to do this without any exceptions? Exceptions are heavyPejsach
If your DNS is broken this won't work as expected, use IP address instead.Tobitobiah
A modified version: public static bool ConnectedToAnyOf(params System.Uri[] url) { using (var wc = new System.Net.WebClient()) { for (var index = 0; index < url.Length; index++) { try { using (wc.OpenRead(url[index])) { return true; } } catch { } } } return false; }Multiplication
@DanielVassallo -- Google is not accessible from some restricted countries (For example, China)Wilcher
Can i somehow implement timeout for that?Hadley
Google returns no response against http://google.com/generate_204Terbium
G
106

There is absolutely no way you can reliably check if there is an internet connection or not (I assume you mean access to the internet).

You can, however, request resources that are virtually never offline, like pinging google.com or something similar. I think this would be efficient.

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;
}
Girosol answered 9/1, 2010 at 0:52 Comment(12)
+1 "There is absolutely no way you can reliably check if there is an internet connection"Riyadh
All this does is check that google is up when you pinged it. If the very next instant after your successful ping the internet goes down then what? There is no point in checking before doing.Capitulary
And how does this contradict with the main statement of my answer?Girosol
Using "google.com" will take more time because it needs to be resolved. Instead, pinging directly using IP will be faster. Pinging to Google Public DNS IP addresses (8.8.8.8 or 8.8.4.4) works fine for me.Chinchilla
In my experience 1000 miliseconds for a timeout is too small and for slow / High latancy internet connections this may report incorrectlyDribble
I would like to reiterate the point that Beware - many schools and offices block the ping protocol. If you are using this method for an application that will be used by clients I would advise against this method of checking internetDribble
Ping is a good first thing to try, but outgoing PING is blocked in lots of schools and companies, so your code should fall back on an HTTP request (preferably to the site you're planning to talk to, and not just to google.com) if the PING fails. Also, the DNS resolution itself can take up to 20 seconds, so that's effectively the minimum timeout value; i.e. lower timeout values can still take 20 seconds before the method returns.Consuelaconsuelo
There is absolutely no point in optimising this approach. Try to do what you wanted to do anyway; act accordingly if it fails. Period.Girosol
is there a way i could implement this asynchronously? using 'SendAsync' complains that it cant convert void to 'PingReply'.Sirloin
@Girosol That's a rather rash statement. I would consider my use case perfectly valid: An online checker that will alert me and perform actions as soon as the internet is back upHomiletics
This solution seems working a lot faster (1-10ms), comparing to others. Also changing from "google.com" to directly a DNS server like "1.1.1.1" make a lot of difference. You can google for fastest DNSMotion
on azure machines the icmp is blocked, so ping will fail.Snelling
C
48

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
Capitulary answered 31/1, 2010 at 15:29 Comment(6)
Right! Just do it - but be prepared for all outcomes.Pullman
Consider the following: You need to Do Something if the network is down for x amout of time (e.g. tracelog, router reset)Weiss
Not the OP, but the reason I want to do this is to AVOID THE DEFAULT 100 SECOND TIMEOUT if Internet connectivity isn't available. The HTTP request is done on a background thread, so the UI thread isn't being blocked, but my app can't exit until the background thread returns from the HTTP request and terminates. Rather than try to find some "happy medium" timeout value, I'd like to just avoid the request altogether if I knew the Internet connection was down.Consuelaconsuelo
My point was that we can't account for when the remote service might become available / unavailable. Also, what about sites that don't respond to pings?Capitulary
Another use case is an online checker that will alert me as soon as my internet is back upHomiletics
Surely it's useful to understand the difference between, "a client can't reach your specific web-service" and, "a client can't reach the internet at all". The reason I'm looking at this 10 years on, is because I want a local app to have different behaviour, on startup, if my web-service is down vs if it can't access the network; how are you supposed to "be prepared" if you don't know what happened?Buckwheat
J
37

NetworkInterface.GetIsNetworkAvailable is very unreliable. Just have some VMware or other LAN connection and it will return wrong result. Also about Dns.GetHostEntry method I were just concerned about whether test URL might be blocked in the environment where my application going to deploy.

So another way I found out is using InternetGetConnectedState method. My code is

[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);         
}
Jacob answered 11/9, 2014 at 5:0 Comment(7)
During testing, I found that InternetGetConnectedState returned true when VMWare player was installed (internet disconnected). Had to disable it in Control Panel\Network and Internet\Network Connections (VMNet1 and VMNet8).Weirdie
Ok Justin Oringer.though i have checked it but have to verify againJacob
Best approach for me, i still check my service connectivity after that, then start the routines... I just wanted to avoid exceptions.Quetzalcoatl
This code only checks if the network cable is plugged in.Timothea
This code is not portable to Linux, MacOS.Bollix
Hi @weePee, I fyou are trying it with .net core then do remember this post is pre .net core era of year 2014Jacob
@Timothea true. other approach is to expose some health check api (which is related to your app) and check it periodicallyJacob
P
16

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.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;
        }
    }
}
Payable answered 29/9, 2016 at 16:32 Comment(1)
This is an interesting approach, and quite different from the other answers! (+1)Mosquito
E
15

A test for internet connection by pinging Google:

new Ping().Send("www.google.com.mx").Status == IPStatus.Success
Electrophorus answered 13/11, 2012 at 18:30 Comment(4)
A description to go along with this answer would be beneficial to more people than just the original author of the question.Nachison
Beware - many schools and offices block the ping protocol. Silly, I know.Pullman
I can't find the ping class. could you please help me. I am working on UWP and the otherways of going through the network information aren't workingWithers
What is www.google.com.mx? Why not ping google.com directly?Drupe
C
13

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
            }));
        }
    }
Coxcombry answered 11/4, 2014 at 10:13 Comment(0)
T
11

I have seen all the options listed above and the only viable option to check wither the internet is available or not is the "Ping" option. Importing [DllImport("Wininet.dll")] and System.Net.NetworkInformation.NetworkInterface.GetAllNetworkInterfaces() Or any other variation of the NetworkInterface class does not work well in detecting the availability of the network.These Methods only check if the network cable is plugged in or not.

The "Ping option"

if(Connection is available) returns true

if(Connection is not available and the network cable is plugged in) returns false

if(Network cable is not plugged in) Throws an exception

The NetworkInterface

if(Internet Is available)Returns True

if(Internet is not Available and Network Cable is Plugged in ) Returns True

if(Network Cable is Not Plugged in )returns false

The [DllImport("Wininet.dll")]

if(Internet Is available)Returns True

if(Internet is not Available and Network Cable is Plugged in ) Returns True

if(Network Cable is Not Plugged in )returns false

So in case of [DllImport("Wininet.dll")] and NetworkInterface There is no way of knowing if internet connection is available.

Timothea answered 21/11, 2016 at 12:35 Comment(1)
This is not true, I imported Wininet.dll, plugged network cable and got correct result for scenario internet not being available.Enchondroma
A
8

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;
}
Arthur answered 29/6, 2014 at 7:24 Comment(3)
Great idea, but like you said might not be perfect. You could cache the bytes sent/received as well for future checks. Still not perfect though.Radium
This code does not work, Please correct. It only checks if network cable is plugged in or not.Timothea
(As per MSDN): "A network connection is considered to be available if any network interface is marked "up" and is not a loopback or tunnel interface." Aside from also checking BytesSent and BytesReceived, you have basically just duplicated the functionality that is already in GetIsNetworkAvailable.Mosquito
G
5

Here's how it is implemented in Android.

As a proof of concept, I translated this code to C#:

var request = (HttpWebRequest)WebRequest.Create("http://g.cn/generate_204");
request.UserAgent = "Android";
request.KeepAlive = false;
request.Timeout = 1500;

using (var response = (HttpWebResponse)request.GetResponse())
{
    if (response.ContentLength == 0 && response.StatusCode == HttpStatusCode.NoContent)
    {
        //Connection to internet available
    }
    else
    {
        //Connection to internet not available
    }
}
Geometer answered 17/5, 2017 at 12:55 Comment(0)
S
5

Introduction

In some scenarios you need to check whether internet is available or not using C# code in windows applications. May be to download or upload a file using internet in windows forms or to get some data from database which is at remote location, in these situations internet check is compulsory.

There are some ways to check internet availability using C# from code behind. All such ways are explained here including their limitations.

  1. InternetGetConnectedState(wininet)

The 'wininet' API can be used to check the local system has active internet connection or not. The namespace used for this is 'System.Runtime.InteropServices' and import the dll 'wininet.dll' using DllImport. After this create a boolean variable with extern static with a function name InternetGetConnectedState with two parameters description and reservedValue as shown in example.

Note: The extern modifier is used to declare a method that is implemented externally. A common use of the extern modifier is with the DllImport attribute when you are using Interop services to call into unmanaged code. In this case, the method must also be declared as static.

Next create a method with name 'IsInternetAvailable' as boolean. The above function will be used in this method which returns internet status of local system

[DllImport("wininet.dll")]
private extern static bool InternetGetConnectedState(out int description, int reservedValue);
public static bool IsInternetAvailable()
{
    try
    {
        int description;
        return InternetGetConnectedState(out description, 0);
    }
    catch (Exception ex)
    {
        return false;
    }
}
  1. GetIsNetworkAvailable

The following example uses the GetIsNetworkAvailable method to determine if a network connection is available.

if (System.Net.NetworkInformation.NetworkInterface.GetIsNetworkAvailable())
{
    System.Windows.MessageBox.Show("This computer is connected to the internet");
}
else
{
    System.Windows.MessageBox.Show("This computer is not connected to the internet");
}

Remarks (As per MSDN): A network connection is considered to be available if any network interface is marked "up" and is not a loopback or tunnel interface.

There are many cases in which a device or computer is not connected to a useful network but is still considered available and GetIsNetworkAvailable will return true. For example, if the device running the application is connected to a wireless network that requires a proxy, but the proxy is not set, GetIsNetworkAvailable will return true. Another example of when GetIsNetworkAvailable will return true is if the application is running on a computer that is connected to a hub or router where the hub or router has lost the upstream connection.

  1. Ping a hostname on the network

Ping and PingReply classes allows an application to determine whether a remote computer is accessible over the network by getting reply from the host. These classes are available in System.Net.NetworkInformation namespace. The following example shows how to ping a host.

protected bool CheckConnectivity(string ipAddress)
{
    bool connectionExists = false;
    try
    {
        System.Net.NetworkInformation.Ping pingSender = new System.Net.NetworkInformation.Ping();
        System.Net.NetworkInformation.PingOptions options = new System.Net.NetworkInformation.PingOptions();
        options.DontFragment = true;
        if (!string.IsNullOrEmpty(ipAddress))
        {
            System.Net.NetworkInformation.PingReply reply = pingSender.Send(ipAddress);
            connectionExists = reply.Status == 
System.Net.NetworkInformation.IPStatus.Success ? true : false;
        }
    }
    catch (PingException ex)
    {
        Logger.LogException(ex.Message, ex);
    }
    return connectionExists;
}

Remarks (As per MSDN): Applications use the Ping class to detect whether a remote computer is reachable. Network topology can determine whether Ping can successfully contact a remote host. The presence and configuration of proxies, network address translation (NAT) equipment, or firewalls can prevent Ping from succeeding. A successful Ping indicates only that the remote host can be reached on the network; the presence of higher level services (such as a Web server) on the remote host is not guaranteed.

Comments/Suggestions are invited. Happy coding......!

Sheerness answered 5/4, 2020 at 11:20 Comment(0)
L
4
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;
    }
}
Lindsy answered 7/9, 2016 at 21:12 Comment(0)
H
4

Try to avoid testing connections by catching the exception. because we really Expect that sometimes we may lose network connection.

 if (NetworkInterface.GetIsNetworkAvailable() &&
     new Ping().Send(new IPAddress(new byte[] { 8, 8, 8, 8 }),2000).Status == IPStatus.Success)
 //is online
 else
 //is offline
Hayes answered 18/3, 2020 at 9:45 Comment(1)
Where does the NetworkInterface come from? EDIT: I find it: System.Net.NetworkInformationTerpineol
R
3

I wouldn't think it's impossible, just not straightforward.

I've built something like this, and yes it's not perfect, but the first step is essential: to check if there's any network connectivity. The Windows Api doesn't do a great job, so why not do a better job?

bool NetworkIsAvailable()
{
    var all = System.Net.NetworkInformation.NetworkInterface.GetAllNetworkInterfaces();
    foreach (var item in all)
    {
        if (item.NetworkInterfaceType == NetworkInterfaceType.Loopback)
            continue;
        if (item.Name.ToLower().Contains("virtual") || item.Description.ToLower().Contains("virtual"))
            continue; //Exclude virtual networks set up by VMWare and others
        if (item.OperationalStatus == OperationalStatus.Up)
        {
            return true;
        }
    }

    return false;
}

It's pretty simple, but it really helps improve the quality of the check, especially when you want to check various proxy configurations.

So:

  • Check whether there's network connectivity (make this really good, maybe even have logs sent back to developers when there are false positives to improve the NetworkIsAvailable function)
  • HTTP Ping
  • (Cycle through Proxy configurations with HTTP Pings on each)
Radium answered 5/10, 2015 at 5:48 Comment(2)
@hackerman this is the non-obvious first step. Coders can work out a quick ping to their own server if it returns true, as a second step. Importantly, this provides an alternative to the flawed windows api method. The rest is details.Radium
To falsify. If no network interface is up, there's definitely no internet. The ui can be updated right away with no delay, no further checks on other hosts.Radium
I
2

Another option is the Network List Manager API which is available for Vista and Windows 7. MSDN article here. In the article is a link to download code samples which allow you to do this:

AppNetworkListUser nlmUser = new AppNetworkListUser();
Console.WriteLine("Is the machine connected to internet? " + nlmUser.NLM.IsConnectedToInternet.ToString());

Be sure to add a reference to Network List 1.0 Type Library from the COM tab... which will show up as NETWORKLIST.

Intensive answered 19/3, 2013 at 17:23 Comment(2)
eeeeww. Using COM hell in .NET?Headon
@Headon Can you maybe explain why one should avoid COM in .NET? Compared to the other solutions I found, the COM solution seems to work pretty well.Allare
C
2

I personally find the answer of Anton and moffeltje best, but I added a check to exclude virtual networks set up by VMWare and others.

public static bool IsAvailableNetworkActive()
{
    // only recognizes changes related to Internet adapters
    if (!System.Net.NetworkInformation.NetworkInterface.GetIsNetworkAvailable()) return false;

    // 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)
            where (!(face.Name.ToLower().Contains("virtual") || face.Description.ToLower().Contains("virtual")))
            select face.GetIPv4Statistics()).Any(statistics => (statistics.BytesReceived > 0) && (statistics.BytesSent > 0));
}
Chrisy answered 3/4, 2017 at 23:30 Comment(1)
FYI from the GetIsNetworkAvailable() docs: A network connection is considered to be available if any network interface is marked "up" and is not a loopback or tunnel interface. I don't know if virtual will always be in the name or description of the inteface. Is that standard?Observable
H
2

The accepted answer succeeds quickly but is very slow to fail when there is no connection. So I wanted to build a robust connection check that would fail faster.

Pinging was said to not be supported in all environments, so I started with the accepted answer and added a WebClient from here with a custom timeout. You can pick any timeout, but 3 seconds worked for me while connected via wifi. I tried adding a fast iteration (1 second), then a slow iteration (3 seconds) if the first one fails. But that made no sense since both iterations would always fail (when not connected) or always succeed (when connected).

I'm connecting to AWS since I want to upload a file when the connection test passes.

public static class AwsHelpers
{
    public static bool GetCanConnectToAws()
    {
        try
        {
            using (var client = new WebClientWithShortTimeout())
            using (client.OpenRead("https://aws.amazon.com"))
                return true;
        }
        catch
        {
            return false;
        }
    }
}

public class WebClientWithShortTimeout: WebClient
{
    protected override WebRequest GetWebRequest(Uri uri)
    {
        var webRequest = base.GetWebRequest(uri);
        webRequest.Timeout = 5000;
        return webRequest;
    }
}
Halflight answered 1/8, 2020 at 21:18 Comment(0)
W
1
bool bb = System.Net.NetworkInformation.NetworkInterface.GetIsNetworkAvailable();

if (bb == true)
    MessageBox.Show("Internet connections are available");
else
    MessageBox.Show("Internet connections are not available");
Washroom answered 23/4, 2013 at 11:18 Comment(4)
Can you add information relating to the speed of this and how this is better than other solutions posted. This will help your answer in fully addressing the question.Skin
The problem with this option is that bb would still be true even when the network is not connected to the internet.Peggiepeggir
While it's true that this doesn't directly answer the question, I think it's still useful to use GetIsNetworkAvailable as a pre-check before attempting to ping Google etc.Fossette
This Code does not tell is Internet Connection is Available or not. If you plug in a network cable without internet it will return true.Timothea
C
1

If you want to notify the user/take action whenever a network/connection change occur.
Use NLM API:

Colander answered 31/7, 2015 at 15:5 Comment(0)
A
1
public static bool Isconnected = false;

public static bool CheckForInternetConnection()
{
    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);
        if (reply.Status == IPStatus.Success)
        {
            return true;
        }
        else if (reply.Status == IPStatus.TimedOut)
        {
            return Isconnected;
        }
        else
        {
            return false;
        }
    }
    catch (Exception)
    {
        return false;
    }
}

public static void CheckConnection()
{
    if (CheckForInternetConnection())
    {
        Isconnected = true;
    }
    else
    {
        Isconnected = false;
    }
}
Aldehyde answered 7/3, 2017 at 16:47 Comment(2)
Please comment your answer. Answers with only code isn't allowed.Gentilesse
It is pretty self explanatory, policing for the sake of policing?Tacita
T
1

Multi threaded version of ping:

  using System;
  using System.Collections.Generic;
  using System.Diagnostics;
  using System.Net.NetworkInformation;
  using System.Threading;


  namespace OnlineCheck
  {
      class Program
      {

          static bool isOnline = false;

          static void Main(string[] args)
          {
              List<string> ipList = new List<string> {
                  "1.1.1.1", // Bad ip
                  "2.2.2.2",
                  "4.2.2.2",
                  "8.8.8.8",
                  "9.9.9.9",
                  "208.67.222.222",
                  "139.130.4.5"
                  };

              int timeOut = 1000 * 5; // Seconds


              List<Thread> threadList = new List<Thread>();

              foreach (string ip in ipList)
              {

                  Thread threadTest = new Thread(() => IsOnline(ip));
                  threadList.Add(threadTest);
                  threadTest.Start();
              }

              Stopwatch stopwatch = Stopwatch.StartNew();

              while (!isOnline && stopwatch.ElapsedMilliseconds <= timeOut)
              {
                   Thread.Sleep(10); // Cooldown the CPU
              }

              foreach (Thread thread in threadList)
              { 
                  thread.Abort(); // We love threads, don't we?
              }


              Console.WriteLine("Am I online: " + isOnline.ToYesNo());
              Console.ReadKey();
          }

          static bool Ping(string host, int timeout = 3000, int buffer = 32)
          {
              bool result = false;

              try
              {
                  Ping ping = new Ping();                
                  byte[] byteBuffer = new byte[buffer];                
                  PingOptions options = new PingOptions();
                  PingReply reply = ping.Send(host, timeout, byteBuffer, options);
                  result = (reply.Status == IPStatus.Success);
              }
              catch (Exception ex)
              {

              }

              return result;
          }

          static void IsOnline(string host)
          {
              isOnline =  Ping(host) || isOnline;
          }
      }

      public static class BooleanExtensions
      {
          public static string ToYesNo(this bool value)
          {
              return value ? "Yes" : "No";
          }
      }
  }
Tobitobiah answered 8/8, 2018 at 7:25 Comment(0)
K
1

Building on @ChaosPandion's answer, to be as sure as possible that the result is correct you can include multiple big sites like others have pointed out. However this should be done asynchronously to avoid too long wait times. Also the WebRequest, HttpWebRequest and HttpWebResponse classes are now obsolete and should be replaced by HttpClient. The following example takes into account the above:

public static async Task<bool> CheckForInternetConnection(TimeSpan? timeoutMs = null, List<string> urls = null)
{
    if (timeoutMs == null)
    {
        timeoutMs = TimeSpan.FromSeconds(10);
    }

    var culture = CultureInfo.InstalledUICulture;
    if (urls == null)
    {
        urls = new List<string>();

        if (culture.Name.StartsWith("fa"))      // Iran
            urls.Add("http://www.aparat.com");
        else if (culture.Name.StartsWith("zh")) // China
            urls.Add("http://www.baidu.com");
        else
        {
            urls.Add("https://www.apple.com/");
            urls.Add("https://www.gstatic.com/generate_204");
        }
    }

    var client = new HttpClient();
    client.Timeout = (TimeSpan)timeoutMs;
    List<Task<string>> tasks = new List<Task<string>>();
    int unresponsiveUrlCount = 0;

    foreach (var url in urls)
    {   
        tasks.Add(client.GetStringAsync(url));             
    }

    Task aggregationTask = null;
    try
    {
        aggregationTask = Task.WhenAll(tasks);
        await aggregationTask;
    }
    catch (Exception)
    {  
        if (aggregationTask?.Exception?.InnerExceptions != null && aggregationTask.Exception.InnerExceptions.Any())
        {
            foreach (var innerEx in aggregationTask.Exception.InnerExceptions)
            {
                unresponsiveUrlCount++;
            }
        }      
    }

    return unresponsiveUrlCount < urls.Count;
}

This method checks all the urls in the list and if they are all inaccessible then it returns false. I have added apple's url, because in my case it loads pretty fast, but it can be replaced with any url.

Karilynn answered 5/9, 2022 at 2:28 Comment(0)
L
0

Use NetworkMonitor to monitoring network state and internet connection.

Sample:

namespace AmRoNetworkMonitor.Demo
{
    using System;

    internal class Program
    {
        private static void Main()
        {
            NetworkMonitor.StateChanged += NetworkMonitor_StateChanged;
            NetworkMonitor.StartMonitor();

            Console.WriteLine("Press any key to stop monitoring.");
            Console.ReadKey();
            NetworkMonitor.StopMonitor();

            Console.WriteLine("Press any key to close program.");
            Console.ReadKey();
        }

        private static void NetworkMonitor_StateChanged(object sender, StateChangeEventArgs e)
        {
            Console.WriteLine(e.IsAvailable ? "Is Available" : "Is Not Available");
        }
    }
}
Leucocyte answered 19/9, 2018 at 5:44 Comment(3)
Nice idea, but checks network availability, not internet availabilityPejsach
This class also check availability of the Internet: SourceCodeLeucocyte
the thing is, I tried it, but it only fired if no network was availablePejsach
C
0

The following code works fine for me:

    Shared Function CheckForInternetConnection() As Boolean
    Try
        System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12
        Using client = New WebClient() With {
        .Proxy = Nothing
    }

            Using client.OpenRead("http://clients3.google.com/generate_204")
                Return True
            End Using
        End Using

    Catch
        Return False
    End Try
End Function
Chaotic answered 28/3 at 11:49 Comment(0)
Y
-1

For my application we also test by download tiny file.

string remoteUri = "https://www.microsoft.com/favicon.ico"

WebClient myWebClient = new WebClient();

try
{
    byte[] myDataBuffer = myWebClient.DownloadData (remoteUri);
    if(myDataBuffer.length > 0) // Or add more validate. eg. checksum
    {
        return true;
    }
}
catch
{
    return false;
}

Also. Some ISP may use middle server to cache file. Add random unused parameter eg. https://www.microsoft.com/favicon.ico?req=random_number Can prevent caching.

Yoakum answered 29/4, 2017 at 13:53 Comment(0)
M
-1

I am having issue on those method on my 3g Router/modem, because if internet is disconnected the router redirects the page to its response page, so you still get a steam and your code think there is internet. Apples (or others) have a hot-spot-dedection page which always returns a certain response. The following sample returns "Success" response. So you will be exactly sure you could connect the internet and get real response !

public static bool CheckForInternetConnection()
{
    try
    {       
        using (var webClient = new WebClient())
        using (var stream = webClient.OpenRead("http://captive.apple.com/hotspot-detect.html"))
        {
            if (stream != null)
            {
                //return true;
                stream.ReadTimeout = 1000;
                using (var reader = new StreamReader(stream, Encoding.UTF8, false))
                {
                    string line;
                    while ((line = reader.ReadLine()) != null)
                    {
                        if (line == "<HTML><HEAD><TITLE>Success</TITLE></HEAD><BODY>Success</BODY></HTML>")
                        {
                            return true;
                        }
                        Console.WriteLine(line);
                    }
                }

            }
            return false;
        }
    }
    catch
    {

    }
    return false;
}
Maryrose answered 11/8, 2017 at 11:11 Comment(0)
C
-2

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.

Croaky answered 22/6, 2017 at 8:25 Comment(0)
C
-4
public static bool HasConnection()
{
    try
    {
        System.Net.IPHostEntry i = System.Net.Dns.GetHostEntry("www.google.com");
        return true;
    }
    catch
    {
        return false;
    }
}

That works

Curtain answered 9/1, 2010 at 1:5 Comment(1)
If you have google's IP in your DNS cache, it won't send a DNS request, so it could return true even if you're not connectedIrrelevancy

© 2022 - 2024 — McMap. All rights reserved.