26

What is the easiest way to check whether internet connection is available programatically?

EDIT: As suggested I tried using the following method, but it is always returning true.

[Flags]
enum InternetConnectionState : int
{
    INTERNET_CONNECTION_MODEM = 0x1,
    INTERNET_CONNECTION_LAN = 0x2,
    INTERNET_CONNECTION_PROXY = 0x4,
    INTERNET_RAS_INSTALLED = 0x10,
    INTERNET_CONNECTION_OFFLINE = 0x20,
    INTERNET_CONNECTION_CONFIGURED = 0x40
}

class Program
{
    [DllImport("WININET", CharSet = CharSet.Auto)]
    static extern bool InternetGetConnectedState(ref InternetConnectionState lpdwFlags, int dwReserved);

static void Main(string[] args)
{
    InternetConnectionState flags = 0;
    bool isConnected = InternetGetConnectedState(ref flags, 0);
    Console.WriteLine(isConnected);
    //Console.WriteLine(flags);
    Console.ReadKey();
}
}

Additional Info (if it helps): I access internet over a shared wifi network.

Prof. Falken
  • 24,226
  • 19
  • 100
  • 173
  • 1
    I'm not sure which API handles it, but in Windows Vista and up actually verifies your connection to the internet. I'm sure this information is exposed in an API, so if you're looking for a solution that works best under Vista and the forthcoming Windows 7, that's the API you're going to want, if you or someone else can figure out which one it is. – jasonh Jul 05 '09 at 23:23
  • Edited the question incorporating the results of the suggested solution. It is not working out for me please help. Thanks! –  Jul 06 '09 at 15:36
  • 1
    I also encountered the same issue long back. Tried out different solutions, but stuck at the same place! – blitzkriegz Jul 06 '09 at 15:50
  • 1
    InternetGetConnectedState is just the first test in the chain - it is intended to tell you if your dial-up connection is connected or not (if you're using dial-up). If you have a lan connection it will (almost) always return true. If you get a true from InternetGetConnectedState you can continue with additional tests, e.g. check if you can do name resolution, if you can access the host(s) that you want to connect to, using the ports and protocols that you will eventually use etc. See my answer further down. – KristoferA Jul 07 '09 at 00:55
  • Possible duplicate of [How do I check for a network connection?](https://stackoverflow.com/questions/520347/how-do-i-check-for-a-network-connection) – T.Todua Sep 09 '19 at 11:10

9 Answers9

21

Here is the Windows API you can call into. It's in wininet.dll and called InternetGetConnectedState.

using System;
using System.Runtime;
using System.Runtime.InteropServices;

public class InternetCS
{
    //Creating the extern function...
    [DllImport("wininet.dll")]
    private extern static bool InternetGetConnectedState( out int Description, int ReservedValue );

    //Creating a function that uses the API function...
    public static bool IsConnectedToInternet( )
    {
        int Desc ;
        return InternetGetConnectedState( out Desc, 0 ) ;
    }
}
Mehrdad Afshari
  • 414,610
  • 91
  • 852
  • 789
colithium
  • 10,269
  • 5
  • 42
  • 57
  • 1
    @colithium: `ref` and `out` should come **before** parameter declaration. `int out` is not valid. – Mehrdad Afshari Jul 05 '09 at 23:35
  • 1
    @Michell: It should compile now. Of course you'll need to add a `Main` method. – Mehrdad Afshari Jul 05 '09 at 23:36
  • Yes, thank you. I reformatted the code I linked to bust missed that. – colithium Jul 06 '09 at 02:12
  • 4
    That one is great for checking connected/disconnected state if you're using dial up connections, but can give false positives if you're using a LAN connection. – KristoferA Jul 06 '09 at 02:54
  • 3
    The MSDN entry for this function says it returns flags like INTERNET_CONNECTION_LAN, INTERNET_CONNECTION_MODEM, and INTERNET_CONNECTION_PROXY which in their descriptions say "Local system uses a **x** to connect to the Internet." And it also says "A return value of TRUE from InternetGetConnectedState indicates that at least one connection to the Internet is available." – colithium Jul 06 '09 at 10:19
  • Alas! It is always returning true! –  Jul 06 '09 at 15:28
  • Yes, if you have a connection to a LAN (wired or wifi) then it will return true because you have a lan connection. This is just the first chain in the test, next you need to check if you can actually do dns name resolution and after than if you can reach the host(s) that you want to reach, using the protocol(s) that you want to use. See my answer... – KristoferA Jul 07 '09 at 00:52
  • The MSDN entry seems to be incorrect then, like I said, it specifically says INTERNET. There is another function inside the same dll called InternetCheckConnection which may be quicker than downloading a webpage to check for a connection – colithium Jul 07 '09 at 02:42
10

here is the best solution I found so far:

public static bool isConnected()
    {
        try
        {
            string myAddress = "www.google.com";
            IPAddress[] addresslist = Dns.GetHostAddresses(myAddress);

            if (addresslist[0].ToString().Length > 6)
            {
                return true;
            }
            else
                return false;

        }
        catch
        {
            return false;
        }

    }

usage:

if(isConnected())
{
    //im connected to the internet
}
else
{
    //not connected
}
Desolator
  • 22,411
  • 20
  • 73
  • 96
10

Microsoft windows vista and 7 use NCSI (Network Connectivity Status Indicator) technic:

NCSI performs a DNS lookup on www.msftncsi.com, then requests http://www.msftncsi.com/ncsi.txt. This file is a plain-text file and contains only the text 'Microsoft NCSI'. NCSI sends a DNS lookup request for dns.msftncsi.com. This DNS address should resolve to 131.107.255.255. If the address does not match, then it is assumed that the internet connection is not functioning correctly.

  • 2
    This is the best answer here. Whereas other answers simply DO NOT provide accurate results (especially System.Net.NetworkInformation.NetworkInterface.GetIsNetworkAvailable() ) and other answers only check DNS (your DNS servers could be down but you still have Internet connectivity) the NCSI approach checks DNS first and if that fails, then tries to connect directly via IP address so it can determine if your internet is really down or your DNS is down. See http://technet.microsoft.com/en-us/library/ee126135%28v=WS.10%29.aspx – public wireless May 01 '14 at 15:54
7

You can check for a network connection using this in .NET 2.0+

System.Net.NetworkInformation.NetworkInterface.GetIsNetworkAvailable();

This will probably just return true for local networks, so it may not work for you.

mkchandler
  • 4,688
  • 3
  • 23
  • 25
  • 2
    MSDN: "A network connection is considered to be available if any network interface is marked "up" and is not a loopback or tunnel interface." So it doesn't guarantee that the network connection is a connection to the internet. Still useful though. – colithium Jul 05 '09 at 23:39
  • Programmers usually check if a specific service/host is available, before their aplication may hung or crush, and then start another routines. So either "ping" method or "dns" method (ping responses may be off - there are no perfect solution). – TomeeNS Jul 18 '22 at 22:19
6

This is a question where the answer really is "it depends". Because it depends on why you want to check and for what kind of connectivity? Do you want to be able to access certain websites/services over http? Send smtp mail? Do dns lookups?

Using a combination of the previous answers is probably the way to go - first use the wininet api from colithium's answer to check if a connection of any kind is available.

If it is, try a couple of dns lookups (see System.Net.Dns ) for either the resources you're interested in or some popular big websites (google, altavista, compuserve, etc...).

Next, you can try pinging (see Roger Willcocks' answer) and/or establishing a socket connection to the same sites. Note that a failed ping could just mean that firewall rules don't allow you to ping.

If you can be more specific as to why you want to check it will be easier to provide an answer that covers your requirements...

KristoferA
  • 12,287
  • 1
  • 40
  • 62
4

Easiest way is to probably check if they can download a file from the web that you know is available. Use the following code to download google's homepage.

WebClient Client = new WebClient ();
String Response;
Response = Client.DownloadString("http://www.google.com");

You should probably wrap that in a Try .... Catch to catch the exception that is thrown when it can't establish a connection.

Kibbee
  • 65,369
  • 27
  • 142
  • 182
  • 7
    But what if The Google fails? *gasp* – colithium Jul 05 '09 at 23:26
  • 4
    Well windows Vista checks that you have an internet connection by pinging Microsoft.com to see if it gets a response. It's not much different :P – Sekhat Jul 06 '09 at 15:57
  • 4
    Thank you Killersponge. Exactly what I was thinking. There has to be some kind of ping to some outside server. Otherwise, how do you really know you have a connection to the internet? How do you know your DNS server is up? How do you know that everything is working end to end. I don't think I had the best answer, but also don't think I deserve -4. Oh well. Maybe over time this will get modded up, so I'm leaving it. I still think this is better (works cross platform, works in Mono) than doing a windows API call. – Kibbee Jul 06 '09 at 23:37
  • 1
    +1, quick and ez test. For higher granularity, break down into separate tests but this is a good quick test to ensure you have http connectivity. If you want to allow http connectivity through a proxy, also set the proxy to the default proxy... – KristoferA Jul 07 '09 at 01:17
  • 1
    +1 This is the most reliable way! Wonder why it is down voted! – softwarematter Aug 13 '09 at 14:56
  • Rather than download the entire HTML page a slightly lighter-weight alternative would be http://www.google.com/favicon.ico – ColinM Jan 14 '16 at 19:30
  • @ColinM If you're really stingy with how much data you transfer, you're probably better off just making the code a little more complex and doing a HEAD request rather than a GET. – Kibbee Jan 14 '16 at 21:04
  • Why not to download the response from the particual host that the program is going to use? Leave that Google in peace, people. ;-) – TomeeNS Jul 18 '22 at 22:23
2

Network Awareness in Windows XP

Network Awareness in Windows Vista and Windows 7

Of course this does not guarantee the web site you plan to visit is not blocked by cooperative firewall rules, the API just checking if a pre-defined web site is reachable.

Sheng Jiang 蒋晟
  • 15,125
  • 2
  • 28
  • 46
0

There are some other options too.

The InfoPath library exposes the "IsDestinationReachable" method, which is a wrapper for the Win API method of the same name. (Looks like Vista doesn't support it)

However, I believe from the Docs that it depends on something like PING, so not necessarily a good test.

Vista + say use the "Network List Manager"

@colithium Google might not be down, but things can also fail out if the DNS lokup interval exceeds the timeout. Not uncommon at home here in NZ, first try fails, second succeeds because the data has propogated back to the ISP DNS or your router cache by the time the second request is done.

Roger Willcocks
  • 1,649
  • 13
  • 27
0

Alternatively you can use DNS lookup to check internet connectivity. This method is faster than Ping method.

public static bool DnsTest()
    {
        try
        {
            System.Net.IPHostEntry ipHe =
                System.Net.Dns.GetHostByName("www.google.com");
            return true;
        }
        catch
        {
            return false;
        }
    }
Faisal Shahzad
  • 170
  • 1
  • 4