Kay
Kay

Reputation:

Determine if internet connection is available

I know that I am not the first to ask the question: How do I find out if my application is online or not? I found this post: StackOverflow. I want to do it with C# and .NET 3.5.

The recommendation is to ping the resource regularly. I am not very happy with that advice. I would rather detect a network change and THEN ping my service to check if it is online.

.NET provides two events for this purpose: NetworkChange.NetworkAvailabilityChanged NetworkChange.NetworkAddressChanged

The first event sounds good but it is fired only if the last network card which is online goes offline. I have several virtual network cards which have been installed by VMWare and those are always online. The second event works but between plugging the network cable and the event, there are often 5 seconds wait time. The Windows tray icon reacts more or less immediately when I am unplugging the cable. What is the best way to be as fast as this tray icon?

My workaround would be to poll NetworkInterface.GetAllNetworkInterfaces() every 500ms and to throw my own event in case that the status of a network adapter changed.

There must be a better solution :)

Upvotes: 13

Views: 14622

Answers (8)

47v1x8s7a
47v1x8s7a

Reputation: 21

People here already told it but there is a diference between network availability and internet availability.
You can have network availability between your network interface and local router but havent internet availability between your local router and your Internet Service Provider (ISP).
There is another problem that testing by ping will tell you about internet availability but not about what network interface is providing it, i think the only way is force ping throught one interface but it isnot possible on windows.

Upvotes: 2

Kay
Kay

Reputation:

I tried the link the Webleeuw suggested, but that code also needs between 4 and 10 seconds to notify me when I plug or unplug my cable. Now, I wanted to know if it just my computer or installation and I wrote my own Observer class which is based on NetworkInterface.GetAllNetworkInterfaces().

And: It works with lightning speed. My app reacts now as quickly as does the tray. The code is far from production code, it is just a quick hack. But this is what I will build upon now :)

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);
        }
    }
}
}

Upvotes: 10

baldy
baldy

Reputation: 5541

Doing a ping is definitely not the cleanest option, especially if it is a web server. Some hosts will disable response to ICMP traffic, so you may ping but not get a response. How about just handling the exception gracefully when it occurs?

Upvotes: 0

Tony Borf
Tony Borf

Reputation: 4660

You can use ping, but I would also build a simple call to return a "yes" if it is online. That way you do know if the server is up and that it is running your code. Also I would only call or ping when a network resource is needed and not continually.

Upvotes: 0

Webleeuw
Webleeuw

Reputation: 7282

About the pinging: depending on how you wish to interpret the results, pinging doesn't seem watertight to me. What if the target times out once in a while, while the connection remains alive? I have yet to see the server that never fails to respond to a ping.

Checking every X millis if the network interface is still online (NetworkInterface.OperationalStatus property) seems more reliable if you'd ask me.

EDIT: This article deals with network address events on a lower level than the System.Net.NetworkInformation.NetworkChange class, or so it seems. On my pc it works very fast, so hopefully you'll be able to use that solution.

Upvotes: 0

Anuraj
Anuraj

Reputation: 19618

Try this using NetworkChange class

using System.Net.NetworkInformation

private void Form5_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");
    }
}

Upvotes: 2

Michael Dillon
Michael Dillon

Reputation: 32392

The windows tray icon is very likely connected to the network card drivers, i.e. below the operating system level which is why it can react so fast.

Since the network card is only one of many links between your client and the service that it accesses on the Internet, the only reliable way to detect whether or not the Internet is available is to poll some service out on the Internet, much the same way that ping does. In TCP/IP networking, this is known as a keepalive, and many protocols will have this built into them as an option.

Upvotes: 0

Tim Ebenezer
Tim Ebenezer

Reputation: 2724

Pinging your resource regularly is the only option that will give you a notification if the service goes offline, as well as if the client goes offline. Potentially you want to handle both situations.

Upvotes: 0

Related Questions