【问题标题】:Programmatically check whether my machine has internet access or not以编程方式检查我的机器是否可以访问互联网
【发布时间】:2013-03-24 14:11:08
【问题描述】:

如何以编程方式检查我的机器是否可以使用 C/C++ 访问互联网,这只是 ping IP 的问题吗?网卡是如何做到的?我的意思是:

我使用的是 Windows 7。

【问题讨论】:

  • Windows 7 已经有这样的服务。这就是任务栏图标的工作方式,让您知道网络有互联网连接。
  • @EricUrban 看起来 Windows 是通过 DNS 查找以及从特定 IP 请求文档的组合来实现的。见Windows 7 Network Awareness
  • @WesleyBaugh 这是准确的。
  • 调用InternetCheckConnection 是正确的方法,除非您尝试从服务中执行此操作。你是?你在写什么样的应用程序?

标签: c++ c connectivity nic


【解决方案1】:

如果你在 Windows 上工作,试试这个

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

【讨论】:

  • 如果用户连接到互联网但无法访问谷歌,比如some fairly large country 中的十亿人之一怎么办?
  • 微软现在还说:“InternetCheckConnection 已弃用。InternetCheckConnection 在使用 Web 代理服务器访问 Internet 的环境中不起作用。根据环境,使用 NetworkInformation.GetInternetConnectionProfile 或 NLM 接口进行检查而是用于 Internet 访问。”
【解决方案2】:

除了 InternetCheckConnection() 函数之外,Win32 API 有一个函数 ( InternetGetConnectedState() ),它为某种形式的 Internet 连接(可用性)返回真/假: p>

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

它还告诉您您拥有哪种类型的互联网连接(LAN、调制解调器、代理等)——这通常很容易知道。

【讨论】:

    【解决方案3】:

    我认为没有这种情况,但你可以试试这个:

    最简单的方法是尝试连接到已知的外部 IP 地址。

    如果在Windows下失败,connect函数会返回SOCKET_ERRORWSAGetLastError通常会返回WSAEHOSTUNREACH(意味着无法将数据包发送到主机)。

    在 Linux 中,您将返回 -1,而 errno 将是 ENETUNREACH。 一些有用的链接:

    1. Link for Windows Sockets

    2. Link for Linux/Unix sockets

    【讨论】:

    • 作为建议,我会尝试连接到少数可以承担负载的“著名” DNS 服务器,例如 8.8.8.8(谷歌的公共 DNS 服务器)。从不止一家公司做不止一个,这样你就可以检测到部分网络故障(例如谷歌宕机),并允许用户“强制互联网访问”,即使你认为它已经关闭(即不要禁用东西只是因为你的启发式有问题)。还要记住要注意连接的数量——每秒钟检查一次是不礼貌的。对于内部测试,请使用您自己拥有的 IP 地址,这样当您搞砸并发送垃圾邮件时,您可以修复它。
    • 更好的是:您通常需要 Internet 访问权限才能访问您自己的服务器。先试试那个。只有当失败(很少)时,您才应该尝试 ping 8.8.8.8,这样您就可以告诉用户是您的服务器还是互联网连接中断了。
    【解决方案4】:

    其实有一个很聪明的方法,包括代码截图here

    它基本上使用 cmd 选项:在 CMD 中点击:route print

    这将使用数组映射路由表,并将查找 0.0.0.0 作为可用的互联网连接。

    我将它与while(true){//the code in here } //check for inet connection , else will sleep for 10 mins and check again 一起使用

    【讨论】:

      【解决方案5】:

      根据 Microsoft API 文档 InternetCheckConnection 已弃用。

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

      windows平台可以使用INetworkListManager接口代替这个API来检查互联网是否连接。

      下面是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;
      }
      

      【讨论】:

      【解决方案6】:

      如果您在 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;
      }
      

      【讨论】:

      • 对于简单的 ping,您可以使用 IcmpSendEcho() 代替,然后您不必通过 system() 生成外部进程。此外,并非所有服务器都响应 ping,或者在特定时刻无法访问服务器,请尝试另一个。
      猜你喜欢
      • 2012-02-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-05-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-09-26
      相关资源
      最近更新 更多