How to detect working internet connection in C#?
Asked Answered
C

7

29

I have a C# code that basically uploads a file via FTP protocol (using FtpWebRequest). I'd like, however, to first determine whether there is a working internet connection before trying to upload the file (since, if there isn't there is no point in trying, the software should just sleep for a time and check again).

Is there an easy way to do it or should I just try to upload the file and in case it failed just try again, assuming the network connection was down?

Callicrates answered 26/3, 2010 at 6:58 Comment(5)
Hey everyone! First of all, thanks for all your answers! I'll go with JaredPar's answer for elegance. @Damien: I know many things could happen, I just want to do a simple: Is there net connection? No? Be back in 30 mins. Yes? Ok, let's try upload. approach. With JaredPar's code it shouldn't be that hard. Nothing much more sophisticated. Thanks for answer nevertheless. @kzen: Pinging is not really a good answer. I, for one, got ICMP requests blocked in my company, so checking it that way would fail even with working connection. Thanks anyway!Callicrates
Andy Shellam: Your answer is basically the same as JaredPar's, I haven't choosed it only because I find JaredPar's looking more elegant. Thanks for your answer anyway!Callicrates
Switched the accpted anwser to the one by Zyo, since it includes loopback/tunnels.Callicrates
firs find ip od any network card second use this #3690972Rosemaryrosemond
using this page [enter link description here][1] [1]: #3690972Rosemaryrosemond
L
33

Just use the plain function

System.Net.NetworkInformation.NetworkInterface.GetIsNetworkAvailable()

that return true of false if the connection is up.

From MSDN: A network connection is considered to be available if any network interface is marked "up" and is not a loopback or tunnel interface.

Keep in mind connectivity is not all, you can be connected to a local network and the router is not connected to the Internet for instance. To really know if you are connected to the internet try the Ping class.

Lovage answered 29/9, 2011 at 20:45 Comment(3)
When disconnecting the cable, the method above returns TRUE.Shit
@Shit Disconnecting the cable doesn't means ALL network are unavailable. You could be on a wifi for instance.Lovage
Ping class looks like the way to go if you want to determine if the user is connected to the internet.Probabilism
H
15

There is a "network availability changed" event which fires when the "up" state of a network connection changes on an interface that is not a tunnel or loopback.

You could read the state of all network adapters on the system at startup, store the current value of "network is available" then listen for this event and change your network state variable when this event fires. This also looks like it will handle dial-up and ISDN connections too.

Granted there are other factors to take into account, such as the NIC is connected to a router (and working) but the Internet connection on the router is down, or the remote host is not responding, but this will at least prevent you trying to make a connection that isn't going to work if there's no network connection to begin with (e.g. VPN or ISDN link is down.)

This is a C# console application - start it running, then disable or unplug your network connection :-)

class Program
{
    static bool networkIsAvailable = false;

    static void Main(string[] args)
    {
        NetworkInterface[] nics = NetworkInterface.GetAllNetworkInterfaces();

        foreach (NetworkInterface nic in nics)
        {
            if (
                (nic.NetworkInterfaceType != NetworkInterfaceType.Loopback && nic.NetworkInterfaceType != NetworkInterfaceType.Tunnel) &&
                nic.OperationalStatus == OperationalStatus.Up)
            {
                networkIsAvailable = true;
            }
        }

        Console.Write("Network availability: ");
        Console.WriteLine(networkIsAvailable);

        NetworkChange.NetworkAvailabilityChanged += new NetworkAvailabilityChangedEventHandler(NetworkChange_NetworkAvailabilityChanged);

        Console.ReadLine();
    }

    static void NetworkChange_NetworkAvailabilityChanged(object sender, NetworkAvailabilityEventArgs e)
    {
        networkIsAvailable = e.IsAvailable;

        Console.Write("Network availability: ");
        Console.WriteLine(networkIsAvailable);
    }
}
Handlebar answered 26/3, 2010 at 8:41 Comment(1)
+1 for realizing that loopbacks and tunnels don't represent a connection. Wish I would have read your answer before trying to implement the accepted answer...Rescue
D
12

I think the best approximation you can use is to check the OperationalStatus value on the NetworkInterface type.

using System.Net.NetworkInformation;

public bool IsNetworkLikelyAvailable() {
  return NetworkInterface
    .GetAllNetworkInterfaces()
    .Any(x => x.OperationalStatus == OperationalStatus.Up);
}

Remember though this is an approximation. The moment this method returns the computer could lose or gain it's internet connection. IMO I would just go straight for the upload and handle the error since you can't prove it won't happen.

Diondione answered 26/3, 2010 at 7:16 Comment(2)
This may return the loopback interface and any tunnel interfaces you have set up. You should probably report 'no' even if either of these reports 'Up'. I know loopback does report 'Up' almost all the time regardless of internet status.Rescue
Thank you for that JaredPar, you've just my application design that much easier.Nickolas
H
6

Think about the situation where your check comes back and says "the connection is there", and before you can start your FTP, the connection drops.

Or where the connection drops part way through your FTP request.

Given that you have to code for these situations anyway, just skip the check

Edit in response to Jason's comments

You can also have the opposite condition occur - that when you check for a connection, none exists, but a moment later, their connection comes up. So now what do you do - do you start nagging the user about the absence of a connection, even though it's now available?

At the end of the day, you're dealing with a large number of resources (your net connection, any intermediate routers, the host, its FTP service). All of these are subject to change outside of your control (as Seth's comment indicated), and no amount of pre-testing will answer the question "will I be able to complete this upload"?

As the OP indicated that he's thinking of a "back off and try again later" approach, then I think it's appropriate to do all of that in the background and not annoy the user at all - unless you've been trying for an "unreasonable" amount of time without success.

Hypoderma answered 26/3, 2010 at 7:17 Comment(2)
+1 A working 'net connection does not imply that the remote host is up and has a working FTP server either.Doubtful
Good answer, but I think you're looking at it back to front: If you don't have a connection, your program shouldn't try to initiate any communications - you could find it locking up in timeouts and/or wasting CPU time on fruitless attempts to talk over a dead link and/or reporting hundreds of stupid errors to the user. Good programs will gracefully detect that the link is offline and stop trying to use it.Vinous
M
6

Can't you just use the Ping Class of the System.Net.NetworkInformation Namespace to ping the FTP server before trying to upload the file?

Melesa answered 26/3, 2010 at 7:20 Comment(2)
Except this will fail if the remote host blocks ping requests - which is good practice and some large hosting providers do.Handlebar
Yes, I thought that was obvious so I didn't bother mentioning it... As others have noticed already there is no way of being absolutely certain that the connection will be available at the exact time of the FTP request with any kind of check, but I feel that a ping is a good enough approximation and a very simple one to implement.Melesa
D
5

if ping is difficult for you, just use webclient.

public static bool CheckForInternetConnection()
{
   try
   {
       using (var client = new WebClient())
       using (var stream = client.OpenRead("http://www.google.com"))
       {
          return true;
       }
   }
   catch
   {
       return false;
   }
}

or any other site. EDIT : you can use http://www.msftncsi.com/ this site. This is site which is run only for internet connectivity. See detailed registry explanation of how windows 7 finds internet connectivity http://blog.superuser.com/2011/05/16/windows-7-network-awareness/

Dol answered 24/1, 2014 at 18:50 Comment(0)
P
2

just wrote async functions to do that:

    private void myPingCompletedCallback(object sender, PingCompletedEventArgs e)
    {
        if (e.Cancelled)
            return;

        if (e.Error != null)
            return;

        if (e.Reply.Status == IPStatus.Success)
        {
            //ok connected to internet, do something...
        }
    }

    private void checkInternet()
    {
        Ping myPing = new Ping();
        myPing.PingCompleted += new PingCompletedEventHandler(myPingCompletedCallback);
        try
        {
            myPing.SendAsync("google.com", 3000 /*3 secs timeout*/, new byte[32], new PingOptions(64, true));
        }
        catch
        {
        }
    }
Propaedeutic answered 15/2, 2014 at 10:3 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.