Компьютерный форум OSzone.net  

Компьютерный форум OSzone.net (http://forum.oszone.net/index.php)
-   AutoIt (http://forum.oszone.net/forumdisplay.php?f=103)
-   -   Наилучший способ проверки наличия интернета (http://forum.oszone.net/showthread.php?t=168703)

sashadeg 27-02-2010 14:26 1357367

Наилучший способ проверки наличия интернета
 
Я знаю 3 способа проверки наличия интернета, может кто знает ещё какой-нибудь?
И какой из них самый оптимальный?

1. Вернуть IP адресс, и если он НЕ равен -1, то инет есть. (долгий)
2. Пинговать google.com или какой-нибудь другой глобальный сервер (я считаю что этот самый оптимальный. ИМХО)
3. _WinAPI_IsNetworkAlive

Вот о последнем хотел узнать поподробнее..., как эта функция проверяет наличие интернета? Тоже пингует? Или как?

_________________________________добавил__________________________________
если _getIP использовать с повторением в 5-10 сек, он не нагрузит интернет? Или как нибудь косвенно повлияет на систему?

madmasles 27-02-2010 15:52 1357442

Цитата:

Цитата sashadeg
как эта функция проверяет наличие интернета »

Откройте C:\Program Files\AutoIt3\Include\WinAPIEx.au3 и найдите нужную Вам функцию.
По-моему, _WinAPI_IsNetworkAlive самый оптимальный способ.

sashadeg 27-02-2010 16:14 1357455

Цитата:

Цитата madmasles
Откройте C:\Program Files\AutoIt3\Include\WinAPIEx.au3 »

Я в том мало что понимаю =)

Просто если стандартные экранчики в трее показывают наличие интернета, то это не значит что он есть =)
Может эта функция берёт инфу из windows? значит не факт =)

Creat0R 27-02-2010 22:29 1357703

Есть вот такой вариант:

Код:

$Connected = IsConnected()

If Not $Connected Then
    MsgBox(0,"","Соединение отсутствует" & @LF & $Connected)
Else
    MsgBox(0,"","Соединение установлено [" & $Connected & "]")
EndIf

Func IsConnected($sPingHost="google.com", $iPingTimeOut=1000)
    Local $iPing_Results = Ping($sPingHost, $iPingTimeOut)
    If $iPing_Results > 0 Then Return $iPing_Results

    Local $hWinInetDll = DllOpen("wininet.dll")
    If $hWinInetDll = -1 Then Return SetError(1, 0, -1)

    Local $aRet = DllCall($hWinInetDll, "int", "InternetGetConnectedState", "int", 0, "int", 0)
    DllClose($hWinInetDll)

    If IsArray($aRet) Then
        $aRet = $aRet[0]
    Else
        $aRet = 0
    EndIf

    If $aRet And $iPing_Results <= 0 Then Return 0

    Return $aRet
EndFunc

Вот тут есть ещё пример.

sashadeg 28-02-2010 07:05 1357860

Creat0R, прикольный скрипт, но Вы сможете рассказать плюсы и минусы этого способа?
Вижу подключается wininet.dll, что он делает?

madmasles 28-02-2010 10:39 1357934

sashadeg,
Вот еще тема:Проверка на подключение к интернету WAN

Цитата:

Цитата sashadeg
Вижу подключается wininet.dll, что он делает? »

Есть бесплатная утилита от NirSoft, в которой можно посмотреть функции в dll: DLL Export Viewer v1.36

Creat0R 28-02-2010 15:58 1358122

Цитата:

Цитата sashadeg
плюсы и минусы этого способа»

Не знаю на счёт минусов, но плюс в том что проверяется подключение более надёжно - сначала проверяется Ping, а затем (если он неудачно отработал) проверяется состояние подключения сети.

Цитата:

Цитата sashadeg
ижу подключается wininet.dll, что он делает? »

Используя эту dll вызывается функция «InternetGetConnectedState», которая проверяет тип подключения к сети.

Creat0R 28-02-2010 16:39 1358145

Вот сделал пример отображающий состояние подключения в GUI (на основе этого примера на vb):

Код:

#include <GUIConstantsEx.au3>
#include <EditConstants.au3>
#include <WindowsConstants.au3>
#include <WinAPI.au3>

$aConnection_State = _InternetGetConnectedState()

GUICreate("_InternetGetConnectedState", 270, 320)

GUICtrlCreateLabel("Connected via MODEM:", 20, 20)
GUICtrlCreateInput($aConnection_State[1][0], 150, 17, 100)

GUICtrlCreateLabel("Connected via LAN:", 20, 50)
GUICtrlCreateInput($aConnection_State[2][0], 150, 47, 100)

GUICtrlCreateLabel("Connected via PROXY:", 20, 80)
GUICtrlCreateInput($aConnection_State[3][0], 150, 77, 100)

GUICtrlCreateLabel("Modem busy:", 20, 110)
GUICtrlCreateInput($aConnection_State[4][0], 150, 107, 100)

GUICtrlCreateLabel("Connection RAS installed:", 20, 140)
GUICtrlCreateInput($aConnection_State[5][0], 150, 137, 100)

GUICtrlCreateLabel("Connection is offline:", 20, 170)
GUICtrlCreateInput($aConnection_State[6][0], 150, 167, 100)

GUICtrlCreateLabel("Connection description:", 20, 200)
GUICtrlCreateEdit("", 20, 220, 230, 80, $ES_WANTRETURN)

For $i = 1 To $aConnection_State[0][0]
    If $aConnection_State[$i][0] Then GUICtrlSetData(-1, "* " & $aConnection_State[$i][1] & @CRLF, 1)
Next

GUISetState(@SW_SHOW)

While 1
    Switch GUIGetMsg()
        Case $GUI_EVENT_CLOSE
            Exit
    EndSwitch
WEnd

Func _InternetGetConnectedState()
    Local Const $INTERNET_CONNECTION_MODEM          = 0x1 ;Local system uses a modem to connect to the Internet.
    Local Const $INTERNET_CONNECTION_LAN            = 0x2 ;Local system uses a local area network to connect to the Internet.
    Local Const $INTERNET_CONNECTION_PROXY          = 0x4 ;Local system uses a proxy server to connect to the Internet.
    Local Const $INTERNET_CONNECTION_MODEM_BUSY    = 0x8 ;No longer used.
    Local Const $INTERNET_RAS_INSTALLED            = 0x10 ;Remote Access Services are installed on this system.
    Local Const $INTERNET_CONNECTION_OFFLINE        = 0x20 ;Local system is in offline mode.
    Local Const $INTERNET_CONNECTION_CONFIGURED    = 0x40 ;Local system has a valid connection to the Internet, but it might or might not be currently connected.

    Local $aRetState[7][2] = [[UBound($aRetState)-1]]
    Local $aRet = DllCall("WinInet.dll", "int", "InternetGetConnectedState", "int*", 0, "int", 0)

    ;For AutoIt < 3.2.10.0 the next line should be used
    ;Local $aRet = DllCall("WinInet.dll", "int", "InternetGetConnectedState", "int_ptr", 0, "int", 0)


    If UBound($aRet) > 0 And $aRet[0] Then
        $aRetState[1][0] = BitAND($aRet[1], $INTERNET_CONNECTION_MODEM) <> 0
        $aRetState[1][1] = "The local system uses a modem to connect to the Internet."

        $aRetState[2][0] = BitAND($aRet[1], $INTERNET_CONNECTION_LAN) <> 0
        $aRetState[2][1] = "The local system connects to the Internet via a LAN"

        $aRetState[3][0] = BitAND($aRet[1], $INTERNET_CONNECTION_PROXY) <> 0
        $aRetState[3][1] = "The local system uses a proxy server to connect to the Internet."

        If $aRetState[3][0] Then
            $aRetState[2][1] &= ", and uses a proxy server."
        Else
            $aRetState[2][1] &= "."
        EndIf

        $aRetState[4][0] = BitAND($aRet[1], $INTERNET_CONNECTION_MODEM_BUSY) <> 0
        $aRetState[4][1] = "The local system's modem is busy with a non-Internet connection."

        $aRetState[5][0] = BitAND($aRet[1], $INTERNET_RAS_INSTALLED) <> 0
        $aRetState[5][1] = "Remote Access Services are installed on this system."

        $aRetState[6][0] = BitAND($aRet[1], $INTERNET_CONNECTION_OFFLINE) <> 0
        $aRetState[6][1] = "The connection is currently offline."
    Else
        Return SetError(1, 0, _WinAPI_GetLastErrorMessage())
    EndIf

    Return $aRetState
EndFunc


madmasles 28-02-2010 17:05 1358163

Creat0R,
"Ругается" :
Цитата:

WARNING: $aRetState: possibly used before declaration.
Добавил в начале
Код:

Dim $aRetState
перестала "ругаться", работает :)

sashadeg 28-02-2010 19:39 1358253

Цитата:

Цитата Creat0R
проверяется подключение более надёжно - сначала проверяется Ping, а затем (если он неудачно отработал) проверяется состояние подключения сети. »

Вот именно это я щас проверил, если ввожу вместо "google.ru" какой-нибудь не сушествующий адрес (чтобы не пропинговало) то всё-равно показывает, будто нету инета.

Может попробовать пропинговать, если пинг не удался, то вернуть IP. А если пинг удался, то сразу показать что инет есть, без возврашения IP?

Creat0R 28-02-2010 19:52 1358259

Цитата:

Цитата madmasles
Ругается »

Это если проверять синтаксиси? по идее я сделал неправильно, нужно явно указать размерность массива:
Код:

Local $aRetState[7][2] = [[6]]
Цитата:

Цитата sashadeg
если ввожу вместо "google.ru" какой-нибудь не сушествующий адрес (чтобы не пропинговало) то всё-равно показывает, будто нету инета »

Всё верно, там нужно указывать существующий адрес, это как бы ещё и проверка на отзывчивость сервера :)

sashadeg 28-02-2010 20:32 1358287

Цитата:

Цитата Creat0R
Всё верно, там нужно указывать существующий адрес, это как бы ещё и проверка на отзывчивость сервера »

хммм... тогда я может неправельно понял вот эту фразу?:
Цитата:

сначала проверяется Ping, а затем (если он неудачно отработал) проверяется состояние подключения сети. »
Зачем тогда проверять состояние подключения сети, если после НЕУДАЧНОЙ пинговки одного сервера выходит сообщение о неработоспособности всего интернета? А если пинг прошел УДАЧНО, то опять же зачем проверять состояние сети? Не думаю что пинг будет при нерабочем состоянии сети :)
или я что-то не понимаю?

Sp01LeR 28-02-2010 21:00 1358314

Цитата:

Цитата sashadeg
Зачем тогда проверять состояние подключения сети, если после НЕУДАЧНОЙ пинговки одного сервера выходит сообщение о неработоспособности всего интернета? »

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

Creat0R 28-02-2010 23:35 1358417

Цитата:

Цитата sashadeg
ачем тогда проверять состояние подключения сети, если после НЕУДАЧНОЙ пинговки одного сервера выходит сообщение о неработоспособности всего интернета? »

Сервер может и не отвечать ;) - Это как бы подстраховка.

centaurvv 03-03-2010 02:22 1359990

Цитата:

Цитата madmasles
Откройте C:\Program Files\AutoIt3\Include\WinAPIEx.au3 и найдите нужную Вам функцию.
По-моему, _WinAPI_IsNetworkAlive самый оптимальный способ »

Что-то я у себя не нахожу этот файл, как впрочем и функцию _WinAPI_IsNetworkAlive в списке доступных функций.
Эт я чего-то еще не докачал? :)

madmasles 03-03-2010 02:56 1359999

centaurvv,
WinAPIEx

Yashied 03-03-2010 05:04 1360035

Можно так (достаточно быстрый способ) или как советовал madmasles.

Код:

#Include <WinAPI.au3>

; #FUNCTION# ========================================================================================================================
; Function Name:    _IsInternet
; Description:      Check for Internet connection.
; Syntax:          _IsInternet (  )
; Parameter(s):    None.
; Return Value(s):  Success: Returns 1.
;                  Failure: Returns 0 and sets the @error flag to non-zero. @extended flag will contain the error code
;                            are specific to the WinINet functions.
;
; Author(s):        Yashied
; Note(s):          -
;====================================================================================================================================

Func _IsInternet()

    Local $Ret = DllCall('wininet.dll', 'int', 'InternetGetConnectedState', 'dword*', 0x20, 'dword', 0)

    If (@error) Then
        Return SetError(1, 0, 0)
    EndIf

    Local $wError = _WinAPI_GetLastError()

    Return SetError((Not ($wError = 0)), $wError, $Ret[0])
EndFunc  ;==>_IsInternet

ConsoleWrite(_IsInternet() & @CR)


El Scorpio 03-03-2010 05:19 1360040

Цитата:

Цитата sashadeg
1. Вернуть IP адресс, и если он НЕ равен -1, то инет есть. (долгий)
2. Пинговать google.com или какой-нибудь другой глобальный сервер (я считаю что этот самый оптимальный. ИМХО)
3. _WinAPI_IsNetworkAlive »

1 - неправильный. Адрес может быть получен от DHCP-сервера локальной сети, но в этой сети для интернета может потребоваться создание коммутируемого подключения
3 - хз,*что за функция, но возражения опять таки, как в п.1
Вариант №4 - проверка активности коммутируемого подключения. Возражения противоположные п.1 - интернет может быть доступен через маршрутизатор локальной сети.

Оптимальным является п.2

sashadeg 03-03-2010 17:14 1360459

Yashied, спасибо. Ну как я понял это та же конфетка что и у Creat0R только в другой бумажке =)

В общем к концу темы я склоняюсь у ДВУМ вариантам... Второй мне нравится больше ,но хз надежный ли он? А первый - давно провереный метод, но иногда глючный.
1. Пинг
2. WinAPI
(см далее)
читать дальше »
Код:

#Include <WinAPI.au3>

; #FUNCTION# ========================================================================================================================
; Function Name:    _IsInternet
; Description:      Check for Internet connection.
; Syntax:          _IsInternet (  )
; Parameter(s):    None.
; Return Value(s):  Success: Returns 1.
;                  Failure: Returns 0 and sets the @error flag to non-zero. @extended flag will contain the error code
;                            are specific to the WinINet functions.
;
; Author(s):        Yashied
; Note(s):          -
;====================================================================================================================================

Func _IsInternet()

    Local $Ret = DllCall('wininet.dll', 'int', 'InternetGetConnectedState', 'dword*', 0x20, 'dword', 0)

    If (@error) Then
        Return SetError(1, 0, 0)
    EndIf

    Local $wError = _WinAPI_GetLastError()

    Return SetError((Not ($wError = 0)), $wError, $Ret[0])
EndFunc  ;==>_IsInternet

ConsoleWrite(_IsInternet() & @CR)


Yashied 03-03-2010 19:52 1360591

Согласно вот этому, какой бы способ не был выбран, без запроса к серверу нельзя однозначно сказать есть ли соединение с интернетом или нет. Вот такая вот путаница...

beve 03-03-2010 21:52 1360690

Цитата:

Цитата sashadeg
Второй мне нравится больше ,но хз надежный ли он? »

Смотря какой интернет, вот у меня adsl, так в этом случае ненадежный и еще и неправильный (показывает наличие или отсутствие связи с модемом-роутером). Поэтому приходится юзать пинг... Но пинг, тоже глючный способ в случае, если связь пропадает с провайдером (но модем еще не успел этого заметить), потому что бывает до 30 секунд не знает есть ли связь, или нету...

sashadeg 04-03-2010 17:18 1361263

Цитата:

Цитата beve
Но пинг, тоже глючный способ в случае, если связь пропадает с провайдером (но модем еще не успел этого заметить), потому что бывает до 30 секунд не знает есть ли связь, или нету... »

У нас с тобой одинаковый интернет =) Та же фигня =)

saavaage 11-08-2010 03:31 1471165

Creat0R, пользуюсь Вашим скриптом (пост http://forum.oszone.net/post-1358145-8.html) для проверки интернета. Недавно столкнулся с таким нюансом:
при полностью отключенном интернете (ни локалки, ни модема), скрипт просто отказался запускаться.
Выскакивает ошибка Error: subscript used with non-Array variable.

FlatX007 11-08-2010 12:08 1471334

_WinAPI_IsNetworkAlive ( ) - WinAPIEx.au3

saavaage 11-08-2010 12:20 1471342

FlatX007, все хорошо, но там нет modem + других нюансов . Кроме того, хотелось бы, чтобы заработал скрипт Creat0R, т.к. он у меня встроен в форму с табами, не хотелось бы ничего менять.
Если можно, хочу попросить Creat0R добавить туда же проверку на WLAN... :wink:

Creat0R 11-08-2010 19:33 1471649

Цитата:

Цитата saavaage
Выскакивает ошибка Error: subscript used with non-Array variable. »

На какую строку указывает ошибка?

FlatX007 11-08-2010 20:06 1471680

53 строка наверно ?

может так ? Local $aRetState[7][2] = [[6]]

Creat0R 11-08-2010 20:26 1471697

Цитата:

Цитата FlatX007
может так »

С этой строкой нет проблем, иначе бы ошибка проявлялась всегда.

saavaage 11-08-2010 20:34 1471704

Creat0R, FlatX007, вот, под виртуалкой получается такой трабл:

Код:

C:\Documents and Settings\?????????????\??? ?????????\????? ?????\AutoIt v3 Script.au3 (11) : ==> Subscript used with non-Array variable.:
GUICtrlCreateInput($aConnection_State[1][0], 150, 17, 100)
GUICtrlCreateInput($aConnection_State^ ERROR

Разница с реальной машиной -только в пути к скрипту.

Creat0R 11-08-2010 20:48 1471717

Цитата:

Цитата saavaage
на 11, 14 и так далее »

Какая версия AutoIt?

saavaage 11-08-2010 20:49 1471718

Creat0R, последняя. Я переписал предыдущий пост - посмотри, плиз.

Creat0R 11-08-2010 20:59 1471722

saavaage,
А так что выдаёт:

Код:

$aConnection_State = _InternetGetConnectedState()
If @error Then MsgBox(0, "", $aConnection_State)


saavaage 11-08-2010 21:11 1471731

Creat0R, "операция успешно завершена" и внизу, после нажатия ОК, опять пишет насчет этой же ошибки

PS Я "кинул" ваши строчки в "голову" скрипта. Верно? Это же была проверка на отработку функции?

Creat0R 11-08-2010 21:33 1471743

Цитата:

Цитата saavaage
операция успешно завершена" »

Хорошо, а если в самой функций заменить:
Код:

If UBound($aRet) > 0 And $aRet[0] Then
на
Код:

If Not @error Then

saavaage 11-08-2010 21:44 1471754

Creat0R, все прошло как положено и при отрубленном и при подключенном интернете. Спасибо! А насчет wlan (wifi) не получиться расширить функционал?

Creat0R 11-08-2010 21:50 1471757

Цитата:

Цитата saavaage
насчет wlan (wifi) не получиться расширить функционал? »

Даже и не знаю, нужно читать MSDN на эту тему.

saavaage 11-08-2010 21:57 1471763

Creat0R, ладно. Попытка -не пытка. Еще раз - thanks a lot!

saavaage 19-08-2010 17:41 1477400

Creat0R, есть еще один вопрос по Вашему скрипту:
Насколько я понимаю, показатель "Connection is offline" должен показывать есть ли сеть, в принципе: false - есть, true - нет. У меня он всегда false. Даже когда выключаю модем, этот параметр не меняется.

Creat0R 19-08-2010 18:14 1477435

Цитата:

Цитата saavaage
показатель "Connection is offline" должен показывать есть ли сеть »

Судя по MSDN, это показывает режим offline соединения, т.е включён ли (поддерживается ли) этот режим.

Цитата:

INTERNET_CONNECTION_OFFLINE - Local system is in offline mode.

saavaage 02-09-2010 13:35 1487119

Creat0R, по-поводу
Цитата:

Цитата Creat0R
насчет wlan (wifi) не получиться расширить функционал? »

нашел на официальном форуме такой топик http://www.autoitscript.com/forum/in...8&hl=wlan&st=0
Возможно, это то, что нужно. Если не сложно, гляньте. Может, удасться обойтись "малой кровью"... Сам не могу попробовать подогнать, т.к. у меня нет wifi


Время: 11:01.

Время: 11:01.
© OSzone.net 2001-