Delphi World - это проект, являющийся сборником статей и малодокументированных возможностей  по программированию в среде Delphi. Здесь вы найдёте работы по следующим категориям: delphi, delfi, borland, bds, дельфи, делфи, дэльфи, дэлфи, programming, example, программирование, исходные коды, code, исходники, source, sources, сорцы, сорсы, soft, programs, программы, and, how, delphiworld, базы данных, графика, игры, интернет, сети, компоненты, классы, мультимедиа, ос, железо, программа, интерфейс, рабочий стол, синтаксис, технологии, файловая система...
Как определить подключён ли компьютер к интернету

Автор: Павел

В последнее время с завидным постояннством появляется вопрос "Как определить, подключен компьютер к интернет или нет?". Позволим себе порассуждать на эту тему и объяснить некоторые из принципов сетевых взаимодействий.

Первое и, пожалуй, самое главное: сам вопрос в нынешней его формулировке является некорректным. Можно только догадываться, что подразумевают под "подключением к интернет" авторы таких вопросов. Если подразумевается физическое подключение, то тут "наука бессильна". Никто и ничто кроме владельца компьютера не сможет сказать, а воткнуты ли в компьютер провода ? Если же подразумевается все-таки некое логическое, программное подключение, то:

Многие из вас наблюдали следующую ситуацию: на компьютере под управлением MS Windows стоит сетевая карта. Допустим, что неправильно настроен драйвер карты или компьютер физически не подключен к сети. При загрузке, система не выдаст никаких ошибок. Только после того, как вы пытаетесь, например, войти в Сетевое окружение, появится сообщение о недоступности сети.

Отсюда:

во-первых, с точки зрения системы (имеется ввиду программная ее часть) нельзя определить, возможна ли в данный момент передача данных (т.е. есть ли то пресловутое "подключение к сети") без самой передачи;

во-вторых, исходя из вышесказанного, вопрос следует привести к виду: "доступен ли некий узел или сервис сети?" (т.е. возможна ли фактическая передача данных?)

Ответом на него и займемся.

Для начала развеем убеждения тех, кто думает, что ответить на этот вопрос можно использовав следующие методы и функции:

Функция InternetGetConnectedState()

Чтобы удостоверится в бесполезности этой функции для наших целей, достаточно посмотреть ее описание в MSDN:

"You cannot rely solely on the fact that InternetGetConnectedState returning TRUE means that you have a valid active Internet connection. It is impossible for InternetGetConnectedState to determine if the entire connection to the Internet is functioning without sending a request to a server. This is why you need to send a request to determine if you are really connected or not. You can be assured however that if InternetGetConnectedState returns TRUE, that attempting your connection will NOT cause you to be prompted to connect to the default Internet Service Provider."

"Вы не можете полагаться только на тот факт, что если ф-ция InternetGetConnectedState возвращает TRUE, это означает наличие активного соединения с Интернет. InternetGetConnectedState не может определить, функционирует ли соединение с Интернет без обращения к серверу..."

Единственно полезным в этой функции является то, что если уж она и возвратила TRUE, то при попытке соединения с Интернет вам не будет предлагаться сначала подключиться к нему.

Функция GetHostByName() - разрешение имен хостов.

Результат, возвращаемый этой функцией, свидетельствующий - согласно MSDN - об успешном ее завершении, говорит всего лишь о том, что в системе правильно настроен и доступен сервис DNS. Как правило, DNS-серверы расположены либо в локальной сети провайдера, либо в локальной сети, к которой подключен наш компьютер (сеть организации, например). Хотя, несомненно, сервера имен и являются частью того, что являет собой сегодня Интернет, и в том и в другом случае успешное разрешение имени хоста скажет нам только о доступности DNS-сервера и не более того.

Определение динамического IP-адреса при подключении по dialup.

Опять-таки, даже если интерфейсу и присвоен динамический IP-адрес, это говорит всего лишь о доступности DHCP-сервера (того самого, который эти адреса, собственно, и назначает), расположенного (кто бы мог подумать!) все в той же локальной сети провайдера.

Определение активности некоего dialup-соединения с неким провайдером.

Главное в этом случае то, что dialup, в общем, никак не связан с Интернет. Это всего лишь средство для подключения нашей программно-аппаратной системы к удаленным программно-аппаратным системам, но не к сетям. Иными словами - факт обнаружения некоего активного в данный момент dialup-соединения говорит лишь о том, что между двумя территориально удаленными друг от друга компьютерами установлена связь с использованием низкоуровневых протоколов межмодемной связи и одного из логических протоколов удаленного взаимодействия (PPP, SLIP и некоторые другие). Это - просто один из возможных каналов связи между двумя компьютерами, который может быть использован для любых целей, в том числе и для взаимодействия с узлами Интернет.

А теперь - правда !

С точки зрения протокола TCP/IP для решения поставленной задачи можно пойти только двумя правильными путями:

Использовать протокол ICMP: утилиты ping, traceroute; (отвечает на вопрос о доступности какого-либо узла, но не говорит о доступности определенного сервиса на этом узле.). Ключевые фунции - IcmpSendEcho() (реализована в ICMP.DLL), InternetCheckConnection() (реализована в WININET.DLL)

Попытаться подключиться к какому-либо Интернет-узлу : либо к необходимому нам либо к наиболее вероятно работающему в данный момент (поисковые сервера, узлы крупных компаний и т.п.), определив программную реакцию на ошибки при вызове функций подключения (самый надежный и достоверный способ проверки как доступности узлов, так и сервисов). Ключевая фунция - Connect() (реализована в WS2_32.DLL)

Пример использования ICMP с помощью ICMP API (1-й путь) описан в соответствующей статье.

Для реализации 2-го пути вполне подойдут готовые компоненты из стандартных палитр Делфи Internet, FastNet (TClientSocket, TPowerSock), а также многие компоненты из состава пакета Indy. Можно сделать тоже самое и реализовав собственный алгоритм с использованием непосредственно Winsock API-вызовов.

В качестве краткого резюме всему вышеизложенному можно сказать следующее :

Интернет, по определению, - глобальная сеть, сеть локальных сетей. "Подключение" к Интернет, с этой точки зрения, есть всего лишь потенциальная (причем вовсе не гарантированная) возможность "общения" компьютера (узла) одной сети с компьютером (узлом) другой сети по установленным для Интернет-сервиса соглашениям с предоставлением такой возможности Интернет-провайдерами обеих сторон. И если такая возможность реализуема в данный интересующий момент времени (целевой компьютер/узел "отвечает" на попытки connect'а или ping'а), можно утверждать, с определенной долей вероятности, что "компьютер подключен к Интернет".

Проект Delphi World © Выпуск 2002 - 2004
Автор проекта: ___Nikolay