tags:

views:

1784

answers:

5

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.

+7  A: 

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 ) ;
    }
}
colithium
this does not compile
@colithium: `ref` and `out` should come **before** parameter declaration. `int out` is not valid.
Mehrdad Afshari
@Michell: It should compile now. Of course you'll need to add a `Main` method.
Mehrdad Afshari
Yes, thank you. I reformatted the code I linked to bust missed that.
colithium
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 - Huagati.com
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
Alas! It is always returning true!
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 - Huagati.com
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
A: 

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
But what if The Google fails? *gasp*
colithium
Then have a set of big sites to test against...
KristoferA - Huagati.com
Looks very wasteful...
Abhijeet Patel
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
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
+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 - Huagati.com
+1 This is the most reliable way! Wonder why it is down voted!
iJeeves
+1  A: 

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.

mc2thaH
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
@colithium I updated my response to reflect that.
mc2thaH
A: 

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  A: 

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 - Huagati.com
I think this is where all of our answers were converging so +1
colithium