从C ++代码

时间:2018-03-15 08:38:12

标签: c++ ping connectivity wininet nic

在为遗留应用程序使用大型代码库时,每当我看到一段代码检查互联网连接是否处于活动状态时,我就会看到以下功能的使用:

InternetCheckConnection(L"http://www.google.com",FLAG_ICC_FORCE_CONNECTION,0)
//or
BOOL bConnected = IsNetworkAlive(&dwSens)
//or
InternetGetConnectedState(&dwReturnedFlag, 0)
//or some other functions

但是存在一种非常简单的方法,您不需要包含其他写代码头文件,即:

if (system("ping www.google.com"))

我的问题是,当我需要查看连接是否可用时,在代码中使用ping有什么缺点(<1>}?

假设我的软件将要运行的机器上不会禁用ping

3 个答案:

答案 0 :(得分:3)

system("ping www.google.com")的缺点是双重的:

  1. 如果有人用自己的命令替换了系统ping命令,它可能会给你错误的结果[并且如果调用ping的进程运行时具有额外的权限,它可以做一些事情“有趣的“有这个特权”。这对于任何system操作都是通用的。

  2. 你正在开始另一个过程,然后在得到答案之前必须运行和关闭[当然要做与InternetCheckConnection相同或多或少的事情 - 查找名称,翻译它到IP地址,发送数据包到该地址,等待响应,解释响应等等。

答案 1 :(得分:0)

根据Microsoft API文档 InternetCheckConnection ,已弃用。

[InternetCheckConnection可用于“需求”部分中指定的操作系统。在后续版本中可能会更改或不可用。而是使用NetworkInformation.GetInternetConnectionProfile或NLM接口。 ]

我们可以使用 INetworkListManager 接口代替该API来检查Windows平台是否已连接Internet。

以下是win32代码库:

        #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;
        }

答案 2 :(得分:0)

如果您使用的是 boost,您可以执行以下操作:

static bool has_internet(net::io_context& ioc) {
    tcp::resolver resolver(boost::asio::make_strand(ioc));

    boost::beast::error_code ec;
    auto endpoints = resolver.resolve("google.com", "80", ec);
    if (endpoints.empty() || ec.failed())
        return false;

    return true;
}