网络状态检测方法分析

现在网上有很多种针对网络状态检测的方法,在此做一个简单的分析和总结。

总体来说一共有七种。

一、 InternetAttemptConnect函数

   这个函数可以说非常简单,只是尝试计算机连接到网络。并不考虑是用什么方式连接。当成功连接到网络的时候,函数返回ERROR_SUCCESS,也就是0。函数的参数永远都是0。

    有一点需要注意的是,当计算机是用“小猫”也就是拨号的方式上网的时候,在执行InternetAttemptConnect这个函数时,会自动激活拨号连接功能。这也就是很多软件使用的拨号连接功能。比如Foxmail和FlashGet。它跟IE的连网状态有时候不统一。

Example:

TCHAR tszDebugMsg[100] = {0};


DWORD dwres = InternetAttemptConnect(0);


if (dwres != ERROR_SUCCESS )
{
   _stprintf_s(tszDebugMsg, 100, TEXT("InternetAttemptConnect failed error code is %d.\r\n"), dwres);
}
else
{
   _stprintf_s(tszDebugMsg, 100, TEXT("We can connect to internet, not consider connect mode~~\r\n"));
}
OutputDebugString(tszDebugMsg);

二、 检查远程主机状态函数:InternetCheckConnection

    这个函数的作用和PING命令是一样的,可以检查远程主机是否连接。如果连接成功返回TRUE,如果连接失败返回FALSE。通过上述的方法只能检测出当前计算机是否物理联网,即网线是否接好,网卡是否能顺利工作,不能确定是否能够实现获得 Internet 服务,即是否能和 ISP 进行 Internet 连接。它跟IE的连网状态有时候不统一。

    缺点:如果断网,或者对应的服务器没开的话,会导致等待,卡死的现象。并且在in proxy environment 下如果设置了proxy server in IE (Internet Option->Connections->Lan Setting->Proxy Server") 获得的返回值一直是false。(这个题一直没找到原因,如有知道原因的还请不吝赐教O(∩_∩)O~)

Example:


BOOL bres = InternetCheckConnection(NULL, FLAG_ICC_FORCE_CONNECTION, 0);
if (!bres)
{
   _stprintf_s(tszDebugMsg, 100, TEXT("InternetCheckConnection failed error code is %d.\r\n"), GetLastError());
}
else
{
   _stprintf_s(tszDebugMsg, 100, TEXT("We can get long-distance host connect, physical connect sucess~~\r\n"));
}
OutputDebugString(tszDebugMsg);

三、 InternetQueryOption函数

    InternetQueryOption 函数的检测结果只能表明当前的 Internet 设置是可用的, 并不能表示计算机一定能访问 Internet,例如网线掉了,网卡突然坏了之类的错误就没法检测出来,要想检测当前计算机是否能够获得 Internet 服务了必须跟InternetCheckConnection()两个结合起来使用。它跟IE的连网状态有时候不统一。

Example:

BYTE btInetSet[100] = {0};
DWORD dwInetSetLen = 100;
BOOL bres = InternetQueryOption(NULL, INTERNET_OPTION_CONNECTED_STATE, btInetSet, &dwInetSetLen);
if (!bres)
{
   _stprintf_s(tszDebugMsg, 100, TEXT("InternetQueryOption failed error code is %d.\r\n"), GetLastError());
}
else
{
   _stprintf_s(tszDebugMsg, 100, TEXT("We can get Internet service, internet settting ok~~\r\n"));
}
OutputDebugString(tszDebugMsg);


四、 检查本地网络连接状态并取得网络连接方式函数:InternetGetConnectedState

缺点是:若当前连接不是用wininet方法建立的,则返回值可能不准确。它跟IE的连网状态有时候不统一。

Example:


bres = InternetGetConnectedState(&dwFlags, 0);
if (!bres)
{
   _stprintf_s(tszDebugMsg, 100, TEXT("InternetGetConnectedState failed error code is %d.\r\n"), GetLastError());
}
else
{
   _stprintf_s(tszDebugMsg, 100, TEXT("InternetGetConnectedState sucess status is 0x%x ~~\r\n"),dwFlags);
}
OutputDebugString(tszDebugMsg);

五、 RAS 方法(Remote Access Service)

    先用RasEnumConnections函数返回整个RAS集合,再用RasGetConnectStatus函数判断第一个 RAS连接的状态。RAS方法的最大优点是:不管当前连接是否是用wininet建立的,RAS 方法均可对在线状态做出正确判断。只能针对adsl拨号上网的用户。(此法只是参照网上解法,具体并未实现过)

六、 注册表法

     在线时,注册表的“\HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\RemoteAccess”处有键值“Remote Connection”,且其值不为零;不在线时,该处无“Remote Connection”键值(当本次系统启动后从未拨号成功时),或者其值为零(表明曾拨号成功,但现在已断掉)。 这个方法很老了,有些系统不支持了。(此法只是参照网上解法,具体并未实现过)

七、ping命令实现

   个人觉得这个方法不是非常好用,在这里就不做赘述了。

====================================================================================

上面的这些方法都或多或少的有些问题,下面是我自己实现的来测试网络状态的函数,它跟IE的连网状态是统一。

(1)       InternetStatus.h

#pragma once

#include <Windows.h>

// Test URL
#define INTENET_STATUS_TESTURL_MS TEXT("http://www.msn.com/")
#define INTENET_STATUS_TESTURL_ASUS_APRPSERVER TEXT("http://www.baidu.com/")

// User Agent
#define USER_AGENT TEXT("SP_InetStatus/1.0")

BOOL IsInternetConnected(void);

(2)       InternetStatus.cpp


// Include
#include "InternetStatus.h"
#include <WinInet.h>
#include <tchar.h>

// Lib
#pragma comment(lib,"wininet.lib")

// Error Msg length
#define DEBUGRMSG_LEN 100


// Error Msg
TCHAR tszDebugMsg[DEBUGRMSG_LEN] = {0};


// MY_InternetOpenUrl Sub Method 
BOOL MY_InternetOpenUrl(HINTERNET hInternet, LPCTSTR lpszUrl)
{
HINTERNET hConnectOpenUrl = NULL;

// Open target url
hConnectOpenUrl = InternetOpenUrl(hInternet, lpszUrl, NULL, 0, INTERNET_FLAG_RELOAD, 0);
if (hConnectOpenUrl == NULL)
{
   _stprintf_s(tszDebugMsg, DEBUGRMSG_LEN, TEXT("\r\n InternetOpenUrl %s failed, error code is %d! \r\n"), lpszUrl, GetLastError());
   OutputDebugString(tszDebugMsg);
   return FALSE;
}

// Close Internet Handle 
InternetCloseHandle(hConnectOpenUrl);

_stprintf_s(tszDebugMsg, DEBUGRMSG_LEN, TEXT("\r\n InternetOpenUrl %s sucess~~ \r\n"), lpszUrl);
OutputDebugString(tszDebugMsg);

return TRUE;

}


// IsInternetConnected Method
BOOL IsInternetConnected()
{
HINTERNET hInternetOpen = NULL;
BOOL brtnInf = TRUE;


hInternetOpen = InternetOpen(USER_AGENT, INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
if (hInternetOpen == NULL)
{
   _stprintf_s(tszDebugMsg, DEBUGRMSG_LEN, TEXT("\r\n InternetOpen failed error code is %d! \r\n"), GetLastError());
   OutputDebugString(tszDebugMsg);
   brtnInf = FALSE;
   goto END_RETURN;
}


BOOL bres = MY_InternetOpenUrl(hInternetOpen, INTENET_STATUS_TESTURL_MS);
if (!bres)
{
   bres = MY_InternetOpenUrl(hInternetOpen, INTENET_STATUS_TESTURL_ASUS_APRPSERVER);
   if (!bres)
   {
    OutputDebugString(TEXT("\r\n InternetOpenUrl Failed after try two URL! \r\n"));
    brtnInf = FALSE;
   }
}


END_RETURN:

// Close HINTERNET
if (hInternetOpen)
{
   InternetCloseHandle(hInternetOpen);
}

return brtnInf;

}

(3) how to using.

#include "InternetStatus.h"


int _tmain(int argc, _TCHAR* argv[])
{

if (IsInternetConnected())
{
   OutputDebugString(TEXT("\r\n Internet Connected ~_~ \r\n"));
}

}

有什么问题大家可以共同讨论O(∩_∩)O~

你可能感兴趣的:(网络,IE,user,service,null,internet)