views:

1163

answers:

7

I have a Windows Forms application. When the user imports a license for my application I'd like to "phone home" (hit an aspx page on the web) and register the license information.

The problem is that the user may not have an internet connection working at that moment. I'd like to test this first. What's the best way to detect if the user has an internet connection available?

I use .NET 2.0 with C#.

Thank you.

+1  A: 

You could throw a ping to the "home" host to see if it returns a reply.

Net::Ping

Ólafur Waage
But if you cannot ping this would not necessarily mean that you can't connect using HTTP(S). (Too) many firewalls block icmp-echo.
Martin C.
+1  A: 

Define 'internet connection'. To me there is no 'internet connection'. There are just tcp/ip connections, dns servers and web servers, etc. The best you can do is try to load the webpage and see if it works. As suggested you could try to ping yourself, but that does not mean the web server is running nor that the page can be loaded. You can only be sure of that when you actually load the page.

Lars Truijens
+2  A: 

I don't see any advantage in testing if the connection is available before performing the request. The connection could still go down after you checked, and there is no reliable way of telling if you request would work before you try it. I also don't see any advantage for the user.

The only legitimate test I would see is if there are any available network interfaces, to avoid anoying the user with a dial-up prompt in case he/she is still on dial-up connection.

Martin C.
+1  A: 

Check the WebRequest.GetResponse Method

// Create a new WebRequest Object to the mentioned URL.
WebRequest myWebRequest=WebRequest.Create("http://www.contoso.com");
Console.WriteLine("\nThe Timeout time of the request before setting is : {0} milliseconds",myWebRequest.Timeout);

// Set the 'Timeout' property in Milliseconds.
myWebRequest.Timeout=10000;

// This request will throw a WebException if it reaches the timeout limit before it is able to fetch the resource.
WebResponse myWebResponse=myWebRequest.GetResponse();

or you could call the InternetGetConnectedState API

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

public static bool IsConnectedToInternet()
{
    int Desc ;
    return InternetGetConnectedState(out Desc, 0);
}
Leon Tayson
+8  A: 

At a PPOE, at least a hundred thousand dollars was spent on this question. The main sticking points:

  1. A lot of the time, an HTTP connection will go out, and come back with a "200 OK" message. Only it's not your site; it the hotel/cafe/whatever router offering to connect you.

  2. The APIs will lie in interesting and creative ways. For example, some of the Windows network APIs return bad connection data if you used to have a modem, but then upgraded to DSL, but didn't run the wizard.

  3. In some (very important) places, trying to connect will start a connection -- on dialup -- with a per-minute charge. Again, at the PPOE they shipped a reasonably popular bit of software that did this at 3:00 AM. Made for some seriously grumpy customers.

  4. Some major ISPs have "unique" software when run on broadband where they weren't clever enough to just use the nice Ethernet and TCP/IP they are given. Instead they use the Ethernet to emulate a modem (which in turn is set up to emulate an Ethernet +tcp/ip setup). It's called PPPOE and it makes it hard to tell what adapter you are trying to use

  5. More and more homes are using DSL and Cabel modems where the computer is "connected", but only to the local box; the local box may have lost connectivity and you won't ever know.

THE ONLY SOLUTION is to try a connection AND validate the return.

SunriseProgrammer
A: 

When I always needed to check for internet connections in my app I would just ping google.com since it seams to never go down.

Superdumbell
I would disrecommend this, as hardcoding anything like this could lead to a maintenance nightmare. What if Google suddenly descided to block icmp-echo-request?
Martin C.
A: 

One method that I've used is to create a webservice with a boolean method that always returns "true". Call it from your app, and if you get any exceptions, or "false", you're not connected.

    [WebMethod]
    public bool IsAvailable()
    {
        return true;
    }

and call it:

        private bool IsOnline()
        {
            Cursor = Cursors.WaitCursor;
            var proxy = new WS();
            bool IsOnline = false;
            try
            {
                IsOnline = proxy.IsAvailable();
            }
            catch (System.Net.WebException WebEx)
            {
                NameValueCollection nvc = new NameValueCollection();
                nvc.Add("WebException Status", WebEx.Status.ToString());
                if (WebEx.Status == System.Net.WebExceptionStatus.ProtocolError)
                {
                    nvc.Add("Status Code", ((System.Net.HttpWebResponse)WebEx.Response).StatusCode.ToString());
                    nvc.Add("Status Description", ((System.Net.HttpWebResponse)WebEx.Response).StatusDescription);
                }
                ExceptionManager.Publish(WebEx, nvc);
            }
            catch (Exception)
            {
                IsOnline = false;
            }
            Cursor = Cursors.Default;
            return IsOnline;
        }
Jon Dewees