Problem
In.NET, what’s the quickest and most efficient way to check for Internet connectivity?
Asked by Mohit Deshpande
Solution #1
public static bool CheckForInternetConnection(int timeoutMs = 10000, string url = null)
{
try
{
url ??= CultureInfo.InstalledUICulture switch
{
{ Name: var n } when n.StartsWith("fa") => // Iran
"http://www.aparat.com",
{ Name: var n } when n.StartsWith("zh") => // China
"http://www.baidu.com",
_ =>
"http://www.gstatic.com/generate_204",
};
var request = (HttpWebRequest)WebRequest.Create(url);
request.KeepAlive = false;
request.Timeout = timeoutMs;
using (var response = (HttpWebResponse)request.GetResponse())
return true;
}
catch
{
return false;
}
}
Answered by ChaosPandion
Solution #2
There is no reliable technique to determine whether or not there is an internet connection (I assume you mean access to the internet).
However, you can make requests for resources that are almost never unavailable, such as pinging google.com or something like. This, I believe, would be effective.
try {
Ping myPing = new Ping();
String host = "google.com";
byte[] buffer = new byte[32];
int timeout = 1000;
PingOptions pingOptions = new PingOptions();
PingReply reply = myPing.Send(host, timeout, buffer, pingOptions);
return (reply.Status == IPStatus.Success);
}
catch (Exception) {
return false;
}
Answered by Leo
Solution #3
Instead of checking, just conduct the action (web request, mail, ftp, etc.) and be prepared for the request to fail, which you will have to do regardless of whether your check was successful.
Consider the following:
1 - check, and it is OK
2 - start to perform action
3 - network goes down
4 - action fails
5 - lot of good your check did
Your activity will fail just as quickly as a ping, etc. if the network is down.
1 - start to perform action
2 - if the net is down(or goes down) the action will fail
Answered by dbasnett
Solution #4
NetworkInterface. The GetIsNetworkAvailable method is quite unreliable. All you need is a VMware or other LAN connection to get an incorrect result. Also, there’s Dns. I was just concerned about the GetHostEntry method since I was worried that the test URL would be restricted in the environment where my application would be deployed.
Another solution I discovered is to use the InternetGetConnectedState function. My code is as follows:
[System.Runtime.InteropServices.DllImport("wininet.dll")]
private extern static bool InternetGetConnectedState(out int Description, int ReservedValue);
public static bool CheckNet()
{
int desc;
return InternetGetConnectedState(out desc, 0);
}
Answered by Kamran Shahid
Solution #5
When you ping google.com, you create a DNS resolution dependency. Pinging 8.8.8.8 works fine, however Google is a long way away. All I have to do is ping the closest thing on the internet to me.
I can use Ping’s TTL function to ping hop #1, then hop #2, and so on until I get a response from a node with a routable address; if that node has a routable address, it is connected to the internet. Hop #1 will be our local gateway/router for the majority of us, and hop #2 will be the first point on the opposite side of our fiber connection or whatever.
Because it pings whatever is closest to me on the internet, this code works for me and responds faster than some of the other solutions in this discussion.
using System.Diagnostics;
using System.Net;
using System.Net.NetworkInformation;
using System.Net.Sockets;
using System.Threading.Tasks;
public static async Task<bool> IsConnectedToInternetAsync()
{
const int maxHops = 30;
const string someFarAwayIpAddress = "8.8.8.8";
// Keep pinging further along the line from here to google
// until we find a response that is from a routable address
for (int ttl = 1; ttl <= maxHops; ttl++)
{
var options = new PingOptions(ttl, true);
byte[] buffer = new byte[32];
PingReply reply;
try
{
using (var pinger = new Ping())
{
reply = await pinger.SendPingAsync(someFarAwayIpAddress, 10000, buffer, options);
}
}
catch (PingException pingex)
{
Debug.Print($"Ping exception (probably due to no network connection or recent change in network conditions), hence not connected to internet. Message: {pingex.Message}");
return false;
}
string address = reply.Address?.ToString() ?? null;
Debug.Print($"Hop #{ttl} is {address}, {reply.Status}");
if (reply.Status != IPStatus.TtlExpired && reply.Status != IPStatus.Success)
{
Debug.Print($"Hop #{ttl} is {reply.Status}, hence we are not connected.");
return false;
}
if (IsRoutableAddress(reply.Address))
{
Debug.Print("That's routable, so we must be connected to the internet.");
return true;
}
}
return false;
}
private static bool IsRoutableAddress(IPAddress addr)
{
if (addr == null)
{
return false;
}
else if (addr.AddressFamily == AddressFamily.InterNetworkV6)
{
return !addr.IsIPv6LinkLocal && !addr.IsIPv6SiteLocal;
}
else // IPv4
{
byte[] bytes = addr.GetAddressBytes();
if (bytes[0] == 10)
{ // Class A network
return false;
}
else if (bytes[0] == 172 && bytes[1] >= 16 && bytes[1] <= 31)
{ // Class B network
return false;
}
else if (bytes[0] == 192 && bytes[1] == 168)
{ // Class C network
return false;
}
else
{ // None of the above, so must be routable
return true;
}
}
}
Answered by Jinlye
Post is based on https://stackoverflow.com/questions/2031824/what-is-the-best-way-to-check-for-internet-connectivity-using-net