Sunday 5 February 2012

How to check if connected to the internet in C#


There are several ways to check whether the internet connection is available in C#. Strangely, the most optimal solution which worked out for me was one that I least expected. Let me outline the three main approaches and describe the advantages and disadvantages of all of them. You can then draw your own conclusion as to what works the best for your task.

#1 – GetIsNetworkAvailable

The first solution is also the simplest of all. Simply call the GetIsNetworkAvailable function and the boolean value will tell you whether the computer is connected to a network. And here lies the problem! It will return true even if you are only connected to a home network and the actual internet connection is down. It will also return true when you have VMware or other visualization software installed because of the network connections associated with VMware are always on.
1
2
3
4
5
6
using System.Net.NetworkInformation;
 
public static bool NetStatus()
{
    return NetworkInterface.GetIsNetworkAvailable();
}

#2 – NetworkAvailabilityChangedEventHandler

The second solution makes use of the System.Net.NetworkInformation namespace which provides access to network traffic data, network address information, and notification of address changes for the local computer. The .NET framework will inform us via a callback when a network availability changes. Although this method is better than continually checking the status by calling the GetIsNetworkAvailable method, it still suffers from the same drawbacks. It will only return false when all the network connections go down and that is a major problem for users of visualization software like VMware and computers connected to multiple networks because the event handler does not provide any information as to which network connection status has changed.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
using System.Net.NetworkInformation;
 
private void Form_Load(object sender, EventArgs e)
{
    NetworkChange.NetworkAvailabilityChanged += new NetworkAvailabilityChangedEventHandler(NetworkChange_NetworkAvailabilityChanged);
}
 
private void NetworkChange_NetworkAvailabilityChanged(object sender, NetworkAvailabilityEventArgs e)
{
    if (e.IsAvailable)
    {
        MessageBox.Show("Available");
    }
    else
    {
        MessageBox.Show("Not available");
    }
}

#3 – NetworkAvailabilityChangedEventHandler

The third approach is the most complicated but you get the full picture of what’s going on with the network connections on the computer. The main functionality is provided by the GetAllNetworkInterfaces function which returns exactly what the name says – an array of all network interfaces. It’s up to you to sort through them and find the information, which you are looking for. The only drawback of this method is that it seems to utilize quite a bit of CPU bandwidth (about 8% on average, which is a lot considering that the timer is set to 500ms). The increased CPU utilization was also the main reason why I decided not to use this approach.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
using System;
using System.Net.NetworkInformation;
using Timer=System.Threading.Timer;
 
namespace NetworkCheckApp
{
    public class NetworkStatusObserver
    {
        public event EventHandler<EventArgs> NetworkChanged;
 
        private NetworkInterface[] oldInterfaces;
        private Timer timer;
 
        public void Start()
        {
            timer = new Timer(UpdateNetworkStatus, null, new TimeSpan(0, 0, 0, 0, 500), new TimeSpan(0, 0, 0, 0, 500));
 
            oldInterfaces = NetworkInterface.GetAllNetworkInterfaces();
        }
 
        private void UpdateNetworkStatus(object o)
        {
            var newInterfaces = NetworkInterface.GetAllNetworkInterfaces();
            bool hasChanges = false;
            if (newInterfaces.Length != oldInterfaces.Length)
            {
                hasChanges = true;
            }
            if (!hasChanges)
            {
                for (int i = 0; i < oldInterfaces.Length; i++)
                {
                    if (oldInterfaces[i].Name != newInterfaces[i].Name || oldInterfaces[i].OperationalStatus != newInterfaces[i].OperationalStatus)
                    {
                        hasChanges = true;
                        break;
                    }
                }
            }
 
            oldInterfaces = newInterfaces;
 
            if (hasChanges)
            {
                RaiseNetworkChanged();
            }
        }
 
        private void RaiseNetworkChanged()
        {
            if (NetworkChanged != null)
            {
                NetworkChanged.Invoke(this, null);
            }
        }
    }
}

#4 – GetHostAddresses

The fourth and final solution, which I have actually used in one of my projects, is based on Dns.GetHostAddresses() function call. The call is very fast and I was not able to detect any significant CPU utilization when it was used on a timer with 500ms interval.
Someone may argue that by using an existing website we are exposing ourselves to a situation where the website might be down and our internet connection diagnoses will be wrong. But really, what are the chances of Google being down any significant amount of time in the next 10 years?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
try
{
    string myAddress = "www.google.com";
    IPAddress[] addresslist = Dns.GetHostAddresses(myAddress);
 
    if (addresslist[0].ToString().Length > 6)
    {
        if (!ConnectionOnline)
        {
            ConnectionOnline = true;
        }
    }
    else
        if (ConnectionOnline)
        {
            ConnectionOnline = false;
        }
}
catch
{
    if (ConnectionOnline)
    {
        ConnectionOnline = false;
    }
}

No comments:

Post a Comment