65.9K
CodeProject 正在变化。 阅读更多。
Home

网络位置感知

starIcon
emptyStarIcon
starIcon
emptyStarIconemptyStarIconemptyStarIcon

1.67/5 (9投票s)

2007年11月25日

4分钟阅读

viewsIcon

34012

downloadIcon

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 信息。

© . All rights reserved.