Программно проверить, есть ли у моей машины доступ в Интернет или нет

Как я могу программно проверить, имеет ли моя машина доступ в Интернет или не использует C/C++, это просто вопрос проверки IP-адреса? Как NIC это делает? Я имею в виду что-то вроде:

введите здесь описание изображения

Я использую Windows 7.


person Aan    schedule 03.04.2013    source источник
comment
В Windows 7 уже есть служба, которая делает это. Так работает значок на панели задач, чтобы вы знали, что сеть подключена к Интернету.   -  person Eric Urban    schedule 03.04.2013
comment
@EricUrban Похоже, что Windows делает это с помощью комбинации поиска DNS и запроса документа с определенного IP-адреса. См. раздел Информация о сети Windows 7.   -  person Wesley Baugh    schedule 03.04.2013
comment
@WesleyBaugh Это точно.   -  person Eric Urban    schedule 03.04.2013
comment
Вызов InternetCheckConnection является правильным подходом, если вы не повторно пытаюсь сделать это из службы. Ты? Какое заявление вы пишете?   -  person Cody Gray    schedule 03.04.2013


Ответы (6)


Если вы работаете в 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;
}
person Nayana Adassuriya    schedule 03.04.2013
comment
Что, если пользователь подключен к Интернету, но не может получить доступ к Google, например, один из миллиардов человек в некоторых довольно большая страна? - person el.pescado; 03.08.2017
comment
Также Microsoft теперь говорит: InternetCheckConnection устарел. InternetCheckConnection не работает в средах, использующих веб-прокси-сервер для доступа в Интернет. В зависимости от среды используйте NetworkInformation.GetInternetConnectionProfile или интерфейсы NLM для проверки доступа к Интернету. - person JCx; 20.07.2018

В дополнение к функции InternetCheckConnection(), Win32 API имеет функцию ( InternetGetConnectedState() ), которая возвращает значение true/false для (наличия) некоторой формы подключения к Интернету:

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

Он также сообщает вам, какой тип подключения к Интернету у вас есть (локальная сеть, модем, прокси и т. д.), что часто бывает очень полезно знать.

person GreatCentralSun    schedule 07.02.2017

Я думаю, что ничего подобного нет, но вы можете попробовать это:

Самый простой способ — попытаться подключиться к известному внешнему IP-адресу.

В случае сбоя в Windows функция подключения вернет SOCKET_ERROR, а WSAGetLastError обычно вернет WSAEHOSTUNREACH (это означает, что пакет не может быть отправлен на хост).

В Linux вы получите -1, а errno будет ENETUNREACH. Некоторые полезные ссылки:

1. Ссылка для сокетов Windows

2. Ссылка для сокетов Linux/Unix

person Kiran    schedule 03.04.2013
comment
В качестве предложения я бы попробовал подключиться к нескольким известным DNS-серверам, которые могут взять на себя нагрузку, например 8.8.8.8 (общедоступный DNS-сервер Google). Выполните более одного действия от более чем одной компании, чтобы вы могли обнаружить частичный сбой сети (например, отключение Google) и разрешить пользователю принудительно подключаться к Интернету, даже если вы считаете, что он не работает (т. е. не отключайте что-либо только потому, что у вашей эвристики проблемы). Также помните, что нужно экономить на количестве подключений — проверять каждую секунду невежливо. Для внутреннего тестирования используйте свои собственные IP-адреса, чтобы, когда вы облажаетесь и спамите, вы могли это исправить. - person Yakk - Adam Nevraumont; 03.04.2013
comment
Даже лучше: обычно вам нужен доступ в Интернет для доступа к вашему собственному серверу. Попробуйте это в первую очередь. Только если это не удается (редко), вы должны попытаться пропинговать 8.8.8.8, чтобы вы могли сообщить пользователю, что это — ваш сервер или интернет-соединение. - person MSalters; 03.04.2013


Согласно документу Microsoft API InternetCheckConnection устарел.

[InternetCheckConnection доступен для использования в операционных системах, указанных в разделе «Требования». Он может быть изменен или недоступен в последующих версиях. Вместо этого используйте NetworkInformation.GetInternetConnectionProfile или интерфейсы NLM. ]

Вместо этого API мы можем использовать Интерфейс INetworkListManager для проверки наличия подключения к Интернету для платформы Windows.

Ниже приведена кодовая база 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;
}
person yeasir007    schedule 27.04.2020
comment
Рэймонд согласен. - person Andreas Rejbrand; 03.11.2020

Следующий код будет работать, если вы работаете в 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;
}
person John Smith    schedule 20.03.2014
comment
Для простой проверки связи вы можете просто использовать IcmpSendEcho() вместо этого вам не нужно запускать внешний процесс через system(). Кроме того, не все серверы отвечают на пинги, или, возможно, сервер в данный момент недоступен, попробуйте другой. - person Remy Lebeau; 12.02.2021