网络位置感知






1.67/5 (9投票s)
2007年11月25日
4分钟阅读

34012

727
获取网络位置通知。
引言
有时我们的应用程序需要了解网络可用性或网络变化。这个应用程序将展示我们的应用程序如何从 NLA(一个 Windows 服务)获取通知。
网络连接可能有三种状态:无网络连接、多个网络连接或单个网络连接。基于此,可能出现以下情况之一。
1) 没有网络连接,并且出现了一个新连接。
2) 系统已存在一个或多个网络连接,并且又出现了一个新连接。
3) 存在多个连接,并且有一个或多个连接断开。
4) 网络连接消失,并且没有可用的网络连接。
以下 API 用于 NLA 通知。
WSAStartup
WSALookupServiceBegin
WSALookupServiceNext
WSALookupServiceEnd
WSANSPIoctl
WSACleanup
WSACreateEvent
API 用法
本节概述如何使用提供的代码中的方法。要从 NLA 服务获取通知,请遵循以下步骤:
1) 要获取 CNetworkAvailabilityCheck 类的实例,请调用 GetNetworkAvailability。
nsnla::CNetworkAvailabilityCheck *ptrNetworkAvailabilityCheck = nsnla::CNetworkAvailabilityCheck::GetNetworkAvailability();
if
{
(!ptrNetworkAvailabilityCheck)//无法获取网络可用性检查实例}
2) 使用 SetNotificationType 设置通知类型。有五种获取通知的方式:轮询 (Pooling)、窗口消息 (Window Message)、事件 (Event)、APC 和完成端口 (completion port)(本应用程序实现了两种通知 - 事件和 APC)。
ptrNetworkAvailabilityCheck->SetNotificationType(APCNotification);
3) 调用 EnumerateLogicalNetwork 来枚举系统中可用的逻辑网络。
return;if
此函数将获取系统中所有可用网络的信息。此函数将逐个获取网络信息并将其插入列表。此函数以 lLocalNetworkInfo 作为输入参数。这是一个本地网络信息的结构。其中包含有关本地网络的信息。
4) 查找连接更改
要获取通知,请调用 LookForConnectionChange。此函数有一个布尔参数,用于决定它是阻塞调用还是非阻塞调用(默认值为 true,即阻塞调用)。
在调用 LookForConnectionChange 之前,可以使用 SetNotificationType 设置通知类型,也可以使用 RegisterAPCNotification 注册 APC 通知的回调函数。
ptrNetworkAvailabilityCheck->RegisterAPCNotification(CUseNetworkAvailabilityDlg::APCInvoked, *
回调函数应遵循 APCNotificationCallback 定义
(!ptrNetworkAvailabilityCheck->EnumerateLogicalNetwork(m_lstNetworkInfo)) this);typedef
如果注册了一个函数,每当 APC 被通知时,它都会调用已注册的函数。
5) 调用 StopLookForConnectionChange 来停止获取通知。
API 详细信息
本节将详细介绍上一节讨论的 NLA 方法。
NLA 初始化
需要初始化套接字库,并且 NLA 使用事件,这些事件也需要创建和初始化。这是通过 InitializeNLA 完成的。
以下函数将执行初始化:
// NLA 类的初始化
bool
{
WSAData wsaData;
WORD wVersionRequested = MAKEWORD(2,2);
{
CNetworkAvailabilityCheck::InitializeNLA()if(0 != WSAStartup(wVersionRequested, &wsaData))//在这里,我们不能像通常的 Windows 套接字那样调用 WSAGetLastError//因为在这种失败的情况下,套接字库本身并未加载OutputDebugString(_T(
}
m_hStopLookingForConnection = WSACreateEvent();
{
}
WSAResetEvent(m_hStopLookingForConnection);
}
"无法初始化套接字库"));return false;if(WSA_INVALID_EVENT == m_hStopLookingForConnection)int iError = WSAGetLastError();return false;return true;
枚举逻辑可用网络
EnumerateLogicalNetwork 将首先调用 InitializeNLA 进行初始化。如果该调用成功,它将使用 CheckAndGetNetworksAvailabilty 枚举当前可用的逻辑网络。此函数使用 Windows API 来获取网络信息。它将使用 WSALookupServiceBegin 发起客户端查询,该函数将返回一个句柄。此句柄可用于后续调用 WSALookupServiceNext。
if
iResult = WSALookupServiceNext(hLookupHandle, LUP_RETURN_ALL, &dwBuffLen, ptrWsaQuerySet);
WSALookupServiceNext 将在最后一个输出参数中返回 WSAQueryset 结构。应持续调用 WSALookupServiceNext 函数,直到它返回 WSA_E_NO_MORE,这表示所有信息都已返回。它将调用 WSALookupServiceEnd 来释放 WSALookupServiceBegin 返回的句柄。
(0 != WSALookupServiceBegin(ptrWsaQuerySet, LUP_RETURN_ALL, &hLookupHandle))
开始查找新连接
有两种调用此 API 的方式:阻塞调用和非阻塞调用。默认情况下为 true,即阻塞调用,它将等待直到网络连接发生变化。如果默认参数为 false,它将立即返回,即它将在另一个线程中等待。由于此应用程序支持两种通知类型,具体取决于应用程序通过 SetNotificationType 设置的通知类型。
StartLookingForConnectionChange 将开始查找连接更改。根据传递给此函数的通知类型,它将设置事件通知或 APC 通知。在设置通知类型后,它将调用 WSANSPIoctl 并等待事件直到收到通知。
StartLookingForConnectionChange 将使用 WSANSPIoctl 设置通知,如下面的代码所示。
if
要设置 APC 回调,必须有一个回调函数,在网络发生更改时会收到通知。NLA 应用程序设置 APC 回调的方式如下。此回调将调用通过 RegisterAPCNotification 注册的客户端回调。
( SOCKET_ERROR == WSANSPIoctl(hLookupHandle, SIO_NSP_NOTIFY_CHANGE, NULL, 0, NULL, 0, &dwBytesReturned, ptrWSACompletion))// APC 通知回调
void
CALLBACK NotifyAPC(DWORD dwError, DWORD cbTransferred, LPWSAOVERLAPPED lpOverlapped, DWORD dwFlags);
停止查找新连接
StopLookForConnectionChange 将停止查找连接更改。
清理
CleanUpNLA 将执行清理并关闭句柄。
还有一个名为 CNLABlob 的类,它将保存 NLA Blob 的信息,并且可以使用该类中可用的公共方法检索 NLA Blob 信息。