Checking internet connection from C++ code

2020-06-06 07:29发布

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.

2条回答
Explosion°爆炸
2楼-- · 2020-06-06 07:38

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;
        }
查看更多
Rolldiameter
3楼-- · 2020-06-06 07:53

The drawback with system("ping www.google.com") is twofold:

  1. 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.

  2. 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].

查看更多
登录 后发表回答