问题
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.
回答1:
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 callingping
is running with extra privileges, it could do something "interesting" with that privilege]. This is generic for anysystem
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].
回答2:
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;
}
来源:https://stackoverflow.com/questions/49294741/checking-internet-connection-from-c-code