Подскажите пожалуйста. С помомощью какой функции можно узнать подключён ли интернет ( т.е. надо узнать состояние интернет соединения - подключено или нет ). И если не трудно опишите её и напишите пожалуйста наглядный пример. Заранее спасибо.
internetCheckConnection site bd "www.ya.ru",0 push 0 push 1 ; тут полюбому оставь единицу ....так как при 0 не всегда работает ..это ;показатель какой сервер для проверки используется push offset site call internetCheckConnection cmp eax, 1
??? Код (Text): InternetGetConnectedState = 0 ;( нет интернета ) InternetCheckConnection = 0 ;( нет интернета ) IP-address = 192.168.1.1 ;( нет интернета ) Но я ведь с этого компа пишу этот пост! Когда так бывает? ))
частенько так бывает. Я так проверяю: Код (Text): internet proc ; проверка соединения с интернет PUSH offset wsa PUSH 202h CALL WSAStartup bad: PUSH offset google CALL gethostbyname test eax, eax jnz good push 5000 call Sleep jmp bad good: Ret internet endp
Какой частый вопрос) Нарыл старые кодесы, глянул: 1. Если интересует именно статус соединений RAS (remote access service - виндовый сервис, управляющий подключениями PPTP (VPN), PPPoE и др, часто используемыми для соединения с интернетом), то смотреть в сторону RasEnumConnections: http://msdn.microsoft.com/en-us/library/aa377284(v=vs.85).aspx Там же есть и example, выводящий список подключенных соединений. Header: ras.h Library: rasapi32.lib Depends: rasapi32.dll 2. Так же стоит посмотреть и на InternetGetConnectedState Код (Text): BOOL WINAPI InternetGetConnectedState( __out LPDWORD lpdwFlags, __reserved DWORD dwReserved); Нужные флажки - ((dwFlags & INTERNET_CONNECTION_CONFIGURED) && (dwFlags & (INTERNET_CONNECTION_LAN|INTERNET_CONNECTION_MODEM)) && !(dwFlags & INTERNET_CONNECTION_OFFLINE)) Но она работает только в одну сторону - отрицательный результат говорит о том, что инета нет, но положительный не обязательно означает наличие активного подклчения. Header: wininet.h Library: wininet.lib Depends: wininet.dll 3. Грязный хак - попробвать подключиться (например, InternetOpen + InternetOpenUrl) 4. Весьма надежно, но все равно "нелегально" - попробовать резолвнуть какое-нибудь доменное имя, например, www.ru 5. Послать ICMP Echo Request (ping) к серверу с известным IP адресом, например, корневому DNS серверу (Например, DNS Root 'A': 198.41.0.4) API: IcmpCreateFile + IcmpSendEcho + IcmpParseReply Header: icmpapi.h Library: iphlpapi.lib Depends: iphlpapi.dll / icmp.dll Все вместе: Код (Text): #include <WinSock2.h> #include <tchar.h> #include <Ras.h> #include <stdio.h> #include <Wininet.h> #include <IntShCut.h> #include <IPExport.h> #include <ICMPApi.h> #include <Ws2tcpip.h> #pragma comment (lib, "wininet") #pragma comment (lib, "rasapi32") #pragma comment (lib, "url") #pragma comment (lib, "Iphlpapi") #pragma comment (lib, "ws2_32") // check ras connections bool IsRasConnected() { DWORD dwCb = sizeof(RASCONN); DWORD dwErr = ERROR_SUCCESS; DWORD dwRetries = 5; DWORD dwConnections = 0; RASCONN* lpRasConn = NULL; // // Loop through in case the information from RAS changes between calls. // while (dwRetries--) { // // If the memory is allocated, free it. // if (NULL != lpRasConn) { HeapFree(GetProcessHeap(), 0, lpRasConn); lpRasConn = NULL; } // // Allocate the size needed for the RAS structure. // lpRasConn = (LPRASCONN) HeapAlloc(GetProcessHeap(), 0, dwCb); if (NULL == lpRasConn) { dwErr = ERROR_NOT_ENOUGH_MEMORY; break; } // // Set the structure size for version checking purposes. // lpRasConn->dwSize = sizeof(RASCONN); // // Call the RAS API then exit the loop if we are successful or an unknown // error occurs. // dwErr = RasEnumConnections( lpRasConn, &dwCb, &dwConnections); if (ERROR_INSUFFICIENT_BUFFER != dwErr) { break; } } // // In the success case, print the names of the connections. // if (ERROR_SUCCESS == dwErr) { DWORD i; printf("\tActive RAS connections:\n"); for (i = 0; i < dwConnections; i++) { printf("\t * [%ws]\n", lpRasConn[i].szEntryName); } } else { printf("\tRAS: RasEnumConnections failed: Error = %d\n", dwErr); } // // Free the memory if necessary. // if (NULL != lpRasConn) { HeapFree(GetProcessHeap(), 0, lpRasConn); lpRasConn = NULL; } return (dwConnections > 0); } void icmp_err (DWORD Status) { switch (Status) { case IP_SUCCESS: printf("\t : Successful\n"); break; case IP_DEST_NET_UNREACHABLE: printf("\t : Destination net unreachable\n"); break; case IP_DEST_HOST_UNREACHABLE: printf("\t : Destination host unreachable\n"); break; case IP_REQ_TIMED_OUT: printf("\t : Request timed out\n"); break; case IP_BAD_DESTINATION: printf("\t : Bad destination\n"); break; case IP_BAD_ROUTE: printf("\t : Bad route\n"); break; default: printf("\t : failure (0x%x)\n", Status); } } // send ICMP Echo Request to the specified host bool IcmpTestEcho (const char *host, bool *pbStatus) { HANDLE hIcmpFile; char IcmpData[] = "abcdefghijklmnopqrstuvwxyz"; char ReplyBuffer[512] = {0}; DWORD ReplySize = sizeof(ReplyBuffer); DWORD IcmpTimeout = 1000; // ICMP echo timeout : 3000 ms bool success = false; if ((hIcmpFile = IcmpCreateFile()) != INVALID_HANDLE_VALUE) { PADDRINFOA addrinfo = 0; if (getaddrinfo (host, 0, 0, &addrinfo) != -1) { DWORD dwRetVal = IcmpSendEcho (hIcmpFile, ((PSOCKADDR_IN)addrinfo->ai_addr)->sin_addr.s_addr, IcmpData, strlen(IcmpData), NULL, ReplyBuffer, ReplySize, IcmpTimeout); if (dwRetVal != 0) { PICMP_ECHO_REPLY EchoReply = (PICMP_ECHO_REPLY) ReplyBuffer; struct in_addr ReplyAddr; ReplyAddr.S_un.S_addr = EchoReply->Address; printf("\tSent icmp message to %s\n", host); if (dwRetVal > 1) { printf("\tReceived %ld icmp message responses\n", dwRetVal); printf("\tInformation from the first response:\n"); } else { printf("\tReceived %ld icmp message response\n", dwRetVal); printf("\tInformation from this response:\n"); } printf("\t Received from %s\n", inet_ntoa( ReplyAddr ) ); printf("\t Status = %ld\n", EchoReply->Status); icmp_err(EchoReply->Status); printf("\t Roundtrip time = %ld milliseconds\n", EchoReply->RoundTripTime); *pbStatus = (success = true); } else { printf("\tCall to IcmpSendEcho failed.\n"); printf("\tIcmpSendEcho returned error: %ld\n", GetLastError() ); icmp_err (GetLastError()); success = false; } } IcmpCloseHandle (hIcmpFile); return success; } else { printf("IcmpCreateFile failed\n"); } return false; } // test inet connection by issuing domain name resolving query (DNS request) // (for domain name 'www.ru') bool InetTestConnect_Dns() { PADDRINFOA addr = 0; const char szDomainName[] = "www.ru"; getaddrinfo (szDomainName, 0, 0, &addr); printf("\tDNS resolving '%s' ... = %s\n", szDomainName, addr ? inet_ntoa (((PSOCKADDR_IN)addr->ai_addr)->sin_addr) : "(no addr)" ); freeaddrinfo (addr); return (addr != 0); } enum ICMP_FAILURE_STATUS { ICMP_SUCCESS, ICMP_ERROR, ICMP_TIMEOUT }; static const char* szIcmpFailureStatus[] = { "Succeeded (OK)", "Failed (ERROR)", "Timed out (ERROR)" }; // test inet connection by sending icmp echo request to the DNS Root Server A ICMP_FAILURE_STATUS InetTestConnect_Icmp() { bool bIcmp = false; const char szDnsRootA[] = "198.41.0.4"; if (!IcmpTestEcho (szDnsRootA, &bIcmp)) return ICMP_ERROR; return bIcmp ? ICMP_SUCCESS : ICMP_TIMEOUT; } // try open WinInet connection bool InetTestConnect_WinInet() { const WCHAR wszServerName[] = L"google.com"; int nServerPort = INTERNET_DEFAULT_HTTP_PORT; bool bStatus = false; HINTERNET hInternet = InternetOpen ( NULL, INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0); if (hInternet != NULL) { printf("\tInternetOpen : internet handle opened\n"); DWORD dwConnectTimeout = 2000; if (!InternetSetOption (hInternet, INTERNET_OPTION_CONNECT_TIMEOUT, &dwConnectTimeout, sizeof(dwConnectTimeout))) return printf("\tInternetSetOption : failed\n"), false; HINTERNET hFile = InternetOpenUrl (hInternet, L"http://google.com", NULL, 0, 0, 0); if (hFile != NULL) { printf("\tInternetOpenUrl : connected\n"); DWORD dwBytesAvailable = -1; if (!InternetQueryDataAvailable (hFile, &dwBytesAvailable, 0, 0)) dwBytesAvailable = -1; else bStatus = true; printf("\tBytes available : %d\n", dwBytesAvailable); InternetCloseHandle (hFile); } else { printf("\tInternetOpenUrl : connect FAILED\n"); } InternetCloseHandle (hInternet); } else { printf("\tInternetOpen : opening internet handle FAILED\n"); } return bStatus; } void main() { printf("RAS connection status : %s\n\n", IsRasConnected() ? "connected (OK)" : "disconnected (ERROR)" ); printf("test inet connection [DNS] : %s\n\n", InetTestConnect_Dns() ? "true (OK)" : "false (ERROR)" ); printf("test inet connection [ICMP] : %s\n\n", szIcmpFailureStatus[InetTestConnect_Icmp()] ); DWORD dwFlags = 0; if (!InternetGetConnectedState (&dwFlags, 0)) return printf("InternetGetConnectedState failed (last err 0x%x)\n", GetLastError()); printf("InternetGetConnectedState : flags = 0x%08x;", dwFlags); if (dwFlags & INTERNET_CONNECTION_CONFIGURED) printf(" Configured"); if (dwFlags & INTERNET_RAS_INSTALLED) printf(" RAS-Installed"); if (dwFlags & INTERNET_CONNECTION_OFFLINE) printf(" Offline"); if (dwFlags & INTERNET_CONNECTION_LAN) printf(" LAN"); if (dwFlags & INTERNET_CONNECTION_MODEM) printf(" Modem"); printf("\n\n"); printf("test inet connection [WinInet] : %s\n\n", InetTestConnect_WinInet() ? "true (OK)" : "false (ERROR)" ); } Вывод при подкллюченном инете: При отключенном инете PS. Да, я видел дату топика ^)
Спасибо, Great. remote access service вещь хорошая. В моем клиническом случае ( интернет раздается через беспроводной роутер ) msdn example вывел диагноз: There are no active RAS connections. Надежность, ты сказал, DNS (берется из кэша) как у гадания по кофейной гуще. Спасибо за ICMP Echo Request (ping) Я в этом слабо разбираюсь, нашел пример Quantum-а http://www.wasm.ru/forum/viewtopic.php?id=14447 И против лома нет приема: InternetOpen Он в INTERNET.zip
Есть один жирненький минус. Есть ли у программы право доступа в интернет? Код (Text): ; Думаю по-умолчанию у этой программы проблем с доступом не будет. invoke WinExec, CSTR("C:\Program Files\Internet Explorer\iexplore.exe http://google.com"), 1 ; Дальше устраивать пытки эксплореру.
для ипв4 есть правила адресации, но тут зависит уже от подключения. за натом такой код ясное дело бесполезен. Код (Text): bool TMain::IsWANAddress(UnicodeString &addr) { // drop locals: //10.0.0.0 - 10.255.255.255 a //172.16.0.0 - 172.31.255.255 b //192.168.0.0 - 192.168.255.255 c //169.254.0.0 -169.254.255.255 dhcp noreply if( !wcsncmp(addr.c_str(), L"192", 3) || !wcsncmp(addr.c_str(), L"127", 3) || !wcsncmp(addr.c_str(), L"10.", 3) || !wcsncmp(addr.c_str(), L"172", 3) || !wcsncmp(addr.c_str(), L"169", 3)) return false; return true; } ну необязательно в кеше.. например так Код (Text): ReverseIP(thisip); status = DnsQuery_W(UnicodeString(thisip).t_str(), DNS_TYPE_PTR, DNS_QUERY_BYPASS_CACHE, pSrvList, &pDnsRecord, NULL); на днях просто кодил одну тему на радстудио, поэтому не удивляйтесь всяким UnicodeString etc )