Programmatically check whether my machine has internet access or not
Asked Answered
F

6

13

How can I programmatically check whether my machine has internet access or not using C/C++, is it just a matter of pinging an IP? How does NIC do it ? I mean something like:

enter image description here

I am using Windows 7.

Farceur answered 3/4, 2013 at 3:34 Comment(4)
Windows 7 already has a service that does this. It's how the task bar icon works to let you know the network has internet connectivity.Pulchi
@EricUrban It looks like Windows does it through a combination of DNS lookup as well as requesting a document from a specific IP. See Windows 7 Network Awareness.Jeremiad
@WesleyBaugh That is accurate.Pulchi
Calling InternetCheckConnection is the correct approach, unless you're trying to do this from a service. Are you? What kind of application are you writing?Sethsethi
H
13

If you work on Windows, just try this

#include <iostream>
#include <windows.h> 
#include <wininet.h>
using namespace std;

int main(){

if(InternetCheckConnection(L"http://www.google.com",FLAG_ICC_FORCE_CONNECTION,0))
{
        cout << "connected to internet";
}

return 0;
}
Hoopla answered 3/4, 2013 at 4:46 Comment(2)
What if user is connected to internet but cannot access google, like one of billion people in some fairly large country?Knickers
Also Microsoft now say: "InternetCheckConnection is deprecated. InternetCheckConnection does not work in environments that use a web proxy server to access the Internet. Depending on the environment, use NetworkInformation.GetInternetConnectionProfile or the NLM Interfaces to check for Internet access instead."Einhorn
S
10

According to Microsoft API document InternetCheckConnection is deprecated.

[InternetCheckConnection is available for use in the operating systems specified in the Requirements section. It may be altered or unavailable in subsequent versions. Instead, use NetworkInformation.GetInternetConnectionProfile or the NLM Interfaces. ]

Instead of this API we can use INetworkListManager interface to check whether Internet is connected or not for windows platform.

Here below is the win32 codebase :

#include <iostream>
#include <ObjBase.h>      // include the base COM header
#include <Netlistmgr.h>

// Instruct linker to link to the required COM libraries
#pragma comment(lib, "ole32.lib")

using namespace std;

enum class INTERNET_STATUS
{
    CONNECTED,
    DISCONNECTED,
    CONNECTED_TO_LOCAL,
    CONNECTION_ERROR
};

INTERNET_STATUS IsConnectedToInternet();

int main()
{
    INTERNET_STATUS connectedStatus = INTERNET_STATUS::CONNECTION_ERROR;
    connectedStatus = IsConnectedToInternet();
    switch (connectedStatus)
    {
    case INTERNET_STATUS::CONNECTED:
        cout << "Connected to the internet" << endl;
        break;
    case INTERNET_STATUS::DISCONNECTED:
        cout << "Internet is not available" << endl;
        break;
    case INTERNET_STATUS::CONNECTED_TO_LOCAL:
        cout << "Connected to the local network." << endl;
        break;
    case INTERNET_STATUS::CONNECTION_ERROR:
    default:
        cout << "Unknown error has been occurred." << endl;
        break;
    }
}

INTERNET_STATUS IsConnectedToInternet()
{
    INTERNET_STATUS connectedStatus = INTERNET_STATUS::CONNECTION_ERROR;
    HRESULT hr = S_FALSE;

    try
    {
        hr = CoInitialize(NULL);
        if (SUCCEEDED(hr))
        {
            INetworkListManager* pNetworkListManager;
            hr = CoCreateInstance(CLSID_NetworkListManager, NULL, CLSCTX_ALL, __uuidof(INetworkListManager), (LPVOID*)&pNetworkListManager);
            if (SUCCEEDED(hr))
            {
                NLM_CONNECTIVITY nlmConnectivity = NLM_CONNECTIVITY::NLM_CONNECTIVITY_DISCONNECTED;
                VARIANT_BOOL isConnected = VARIANT_FALSE;
                hr = pNetworkListManager->get_IsConnectedToInternet(&isConnected);
                if (SUCCEEDED(hr))
                {
                    if (isConnected == VARIANT_TRUE)
                        connectedStatus = INTERNET_STATUS::CONNECTED;
                    else
                        connectedStatus = INTERNET_STATUS::DISCONNECTED;
                }

                if (isConnected == VARIANT_FALSE && SUCCEEDED(pNetworkListManager->GetConnectivity(&nlmConnectivity)))
                {
                    if (nlmConnectivity & (NLM_CONNECTIVITY_IPV4_LOCALNETWORK | NLM_CONNECTIVITY_IPV4_SUBNET | NLM_CONNECTIVITY_IPV6_LOCALNETWORK | NLM_CONNECTIVITY_IPV6_SUBNET))
                    {
                        connectedStatus = INTERNET_STATUS::CONNECTED_TO_LOCAL;
                    }
                }

                pNetworkListManager->Release();
            }
        }

        CoUninitialize();
    }
    catch (...)
    {
        connectedStatus = INTERNET_STATUS::CONNECTION_ERROR;
    }

    return connectedStatus;
}
Shelah answered 27/4, 2020 at 23:8 Comment(1)
Raymond agrees.Hebdomad
S
6

In addition to the InternetCheckConnection() function, The Win32 API has a function ( InternetGetConnectedState() ) which returns a true/false for (the availability of) some form of internet connectivity:

https://msdn.microsoft.com/en-us/library/windows/desktop/aa384702(v=vs.85).aspx

It also tells you what type of connection to the internet you have(LAN, modem, Proxy etc) - which can often be very handy to know.

Serotonin answered 7/2, 2017 at 2:37 Comment(0)
M
4

There is nothing of that sort I think, but you can try this:

The easiest way is to try to connect to a known outside IP address.

If it fails in Windows, the connect function will return SOCKET_ERROR, and WSAGetLastError will usually return WSAEHOSTUNREACH (meaning the packet couldn't be sent to the host).

In Linux, you'll get back a -1, and errno will be ENETUNREACH. Some useful links:

1. Link for Windows Sockets

2. Link for Linux/Unix sockets

Misrule answered 3/4, 2013 at 3:40 Comment(2)
As a suggestion, I'd try connecting to a handful of "famous" DNS servers which can take the load, like 8.8.8.8 (google's public DNS server). Do more than one from more than one company, so you can detect partial network failure (such as google going down), and allow the user to "force internet access" even if you think it is down (ie, don't disable stuff just because your heuristic is having issues). Also remember to be sparing in how much you connect -- checking every second is impolite. For internal testing, use your own owned IP addresses, so when you screw up and spam, you can fix it.Stagecoach
Even better: you generally need Internet access to access your own server. Try that first. Only if that fails (rarely) should you try to ping 8.8.8.8, so you can tell the user whether it's your server or the internet connection that's down.Monomial
T
2

There is actually a very smart way including code snip here.

It basically using the cmd option: While in CMD hit: route print.

This will map routing table with an array and will look for 0.0.0.0 as an available internet connection.

I used it with a while(true){//the code in here } //check for inet connection , else will sleep for 10 mins and check again

Taboret answered 23/2, 2015 at 12:25 Comment(0)
M
-1

The following code will work, if you're on windows:

#include <iostream>
#include <windows.h>

int main(){

  if (system("ping www.google.com")){
          std::cout<<"\nNot connnected to the internet\n\n";
  }
  else{
          std::cout<<"\nConnected to the internet\n\n";

  }
  system("pause");
  return 0;
}
Maundy answered 20/3, 2014 at 5:32 Comment(1)
For a simple ping, you could just use IcmpSendEcho() instead, then you don't have to spawn an external process via system(). Also, not all servers respond to pings, or maybe the server is not reachable at that particular moment, try another one.Biblicist

© 2022 - 2024 — McMap. All rights reserved.