While working with large codebase for legacy applications, whenever I have seen a piece of code that checks whether an internet connection is active or not, I have mostly seen the uses of functions such as:
InternetCheckConnection(L"http://www.google.com",FLAG_ICC_FORCE_CONNECTION,0)
//or
BOOL bConnected = IsNetworkAlive(&dwSens)
//or
InternetGetConnectedState(&dwReturnedFlag, 0)
//or some other functions
but there exists a very very simple way to do this where you wouldn't need to include other header files of write code, that is:
if (system("ping www.google.com"))
My question is that what are the drawbacks, if any, to use ping
from the code when I need to see if a connection is available or not?
Assuming that ping
is not going to be disabled on the machines where my software is going to run.
The drawback with system("ping www.google.com")
is twofold:
If someone replaced the system ping
command with their own, it could give you the wrong results [and if the process calling ping
is running with extra privileges, it could do something "interesting" with that privilege]. This is generic for any system
operation.
You are starting another process, which then has to run and shut down before you get the answer [and of course do more or less the same things that InternetCheckConnection
does - look up the name, translate it to an IP address, send packet to that address, wait for a response, interpret that response, and so on].
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;
}