c++中Soft AP (HostedNetwork / 承载网络) 功能

要编码实现Soft AP,首先需要添加相应的头文件及lib库

 代码如下 复制代码
 
#include <wlanapi.h>
#include <iphlpapi.h>
#include <winsock2.h>
#pragma comment(lib, "ws2_32.lib")
#pragma comment(lib, "Wlanapi.lib")
#pragma comment(lib, "IPHLPAPI.lib")

 
其中,wlanapi.h是无线网络API的声明文件,函数名一般以Wlan开头。iphlpapi.h用于调用GetAdapterInfo函数,获取网络虚拟接口信息。
 
和winsock套接字编程类似,Wlan库使用前需获得句柄,并进行版本协商,只不过都在WlanOpenHandle实现了。使用完句柄后,调用WlanCloseHandle关闭以释放资源。
WlanOpenHandle原形如下:
 

 代码如下 复制代码
DWORD WINAPI WlanOpenHandle(
  _In_        DWORD dwClientVersion,
  _Reserved_  PVOID pReserved,
  _Out_       PDWORD pdwNegotiatedVersion,
  _Out_       PHANDLE phClientHandle
);

 
 
dwClientVersion指定程序期望使用的Wlan版本,使用宏WLAN_API_VERSION代替。从vista开始,版本号为2,xp系统为1。协商后的版本通过参数pdwNegotiatedVersion返回,通过检查主版本号来验证(如下代码所示)。句柄通过phClient返回。
 

 代码如下 复制代码
DWORD dwError = 0;
    DWORD dwServiceVersion = 0;
    HANDLE hClient = NULL;
if (ERROR_SUCCESS != (dwError = WlanOpenHandle(
        WLAN_API_VERSION,  
        NULL,               // reserved
        &dwServiceVersion,
        &hClient
        )))
    {
        return -1;
    }
// check service version
    if (WLAN_API_VERSION_MAJOR(dwServiceVersion) < WLAN_API_VERSION_MAJOR(WLAN_API_VERSION_2_0))
    {
        WlanCloseHandle(hClient, NULL);
    }

 
 
启动承载网络前,需要将模式配置为allow状态,并设置SSID和密码。可以调用WlanHostedNetworkSetProperty进行设置,WlanHostedNetworkSetProperty原型如下:
 

 代码如下 复制代码
DWORD WINAPI WlanHostedNetworkSetProperty(
  _In_        HANDLE hClientHandle,
  _In_        WLAN_HOSTED_NETWORK_OPCODE OpCode,
  _In_        DWORD dwDataSize,
  _In_        PVOID pvData,
  _Out_opt_   PWLAN_HOSTED_NETWORK_REASON pFailReason,
  _Reserved_  PVOID pvReserved
);
 

 
其中hClientHandle是我们之前调用WlanOpenHnadle获得的句柄;dwDataSize指定了pvData缓冲区的大小,而pvData指向的变量类型取决与OpCode的取值。OpCode为WLAN_HOSTED_NETWORK_OPCODE枚举,如果指定为wlan_hosted_network_opcode_enable,那么pvData传入一个BOOL型的变量指针,用于指示承载网络模式为允许还是禁止(allow/disallow);如果OpCode为wlan_hosted_network_opcode_connection_settings,那么pvData指向WLAN_HOSTED_NETWORK_CONNECTION_SETTINGS结构体,指定承载网络的SSID和最大连接数目(peer count).
 
示例代码:

 代码如下 复制代码
 
// 设置承载网络模式为允许
    BOOL bIsAllow = TRUE;
    WLAN_HOSTED_NETWORK_REASON dwFailedReason;
    DWORD dwReturnValue = WlanHostedNetworkSetProperty(hWlanClient,
        wlan_hosted_network_opcode_enable,
        sizeof(BOOL),
        &bIsAllow,
        &dwFailedReason,
        NULL);
    if(ERROR_SUCCESS != dwReturnValue)
    {
        return -1;
    }
 
    // 设置承载网络的SSID和最大连接数
    WLAN_HOSTED_NETWORK_CONNECTION_SETTINGS wlanConnectionSetting;
    memset(&wlanConnectionSetting, 0, sizeof(WLAN_HOSTED_NETWORK_CONNECTION_SETTINGS));
    // WLAN_HOSTED_NETWORK_CONNECTION_SETTINGS中的SSID字段必须为ANSI类型,因此如果程序使用的是Unicode,则需要做转换。
#ifdef _UNICODE
    WideCharToMultiByte(CP_ACP,
        0,
        strSSID.GetBuffer(0),   // 保存SSID的CString类型
        strSSID.GetLength(),    // SSID字符串的长度
        (LPSTR)wlanConnectionSetting.hostedNetworkSSID.ucSSID,
        32,
        NULL,
        NULL);
#else
    memcpy(wlanConnectionSetting.hostedNetworkSSID.ucSSID, strSSID.GetBuffer(0), strlen(strSSID.GetBuffer(0)));
#endif 
    wlanConnectionSetting.hostedNetworkSSID.uSSIDLength = strlen((const char*)wlanConnectionSetting.hostedNetworkSSID.ucSSID);
    wlanConnectionSetting.dwMaxNumberOfPeers = 100;  
    dwReturnValue = WlanHostedNetworkSetProperty(m_hWlanClient,
        wlan_hosted_network_opcode_connection_settings,
        sizeof(WLAN_HOSTED_NETWORK_CONNECTION_SETTINGS),
        &wlanConnectionSetting,
        &dwFailedReason,
        NULL);
    if(ERROR_SUCCESS != dwReturnValue)
    {
        return -1;
    }
 

调用WlanHostedNetworkSetSecondaryKey函数,设置承载网络的连接密码,函数原型如下:
 

 代码如下 复制代码
DWORD WINAPI WlanHostedNetworkSetSecondaryKey(
  _In_        HANDLE hClientHandle,
  _In_        DWORD dwKeyLength,
  _In_        PUCHAR pucKeyData,
  _In_        BOOL bIsPassPhrase,
  _In_        BOOL bPersistent,
  _Out_opt_   PWLAN_HOSTED_NETWORK_REASON pFailReason,
  _Reserved_  PVOID pvReserved
);
 

 
hClientHandle是我们之前调用WlanOpenHnadle获得的句柄;
bIsPassPhrase表明传入pucKeyData的密码是否为口令格式,如果是口令格式,则是8-63位的ASCII字符串,该参数设置为TRUE;如果为16进制的binary,参数设置为FALSE;
dwKeyLength是密码缓冲区的长度,密码为口令格式时,必须包括结尾的''
pucKeyData如果字符串,则必须为ANSI类型,因此如果IDE环境将字符串配置为UNICODE,需要做转换,可使用WideCharToMultiByte,或者T2A,W2A宏。
bPersistent用来指示密码是否是持久的。如果不是,那么该密码只在本次启动有效;否则下次启动Soft AP依然使用本次设置的密码。
 
示例代码:

 代码如下 复制代码
UCHAR keyBuf[100] = {0};
#ifdef _UNICODE
    WideCharToMultiByte(CP_ACP,
        0,
        strSecondaryKey.GetBuffer(0),
        strSecondaryKey.GetLength(),
        (LPSTR)keyBuf,
        100,
        NULL,
        NULL);
#else
    memcpy(keyBuf, strSecondaryKey.GetBuffer(0), strlen(strSecondaryKey.GetBuffer(0)));
#endif
    dwReturnValue = WlanHostedNetworkSetSecondaryKey(m_hWlanClient,
        strlen((const char*)keyBuf) + 1,
        keyBuf,
        TRUE,
        FALSE,
        &dwFailedReason,
        NULL);
    if(ERROR_SUCCESS != dwReturnValue)
    {
        return -1;
    }

 
 
启动或者停止Soft AP,需要用到如下四个函数:
 

 代码如下 复制代码

DWORD WINAPI WlanHostedNetworkStartUsing(
  _In_        HANDLE hClientHandle,
  _Out_opt_   PWLAN_HOSTED_NETWORK_REASON pFailReason,
  _Reserved_  PVOID pvReserved
);

DWORD WINAPI WlanHostedNetworkStopUsing(
  _In_        HANDLE hClientHandle,
  _Out_opt_   PWLAN_HOSTED_NETWORK_REASON pFailReason,
  _Reserved_  PVOID pvReserved
);
DWORD WINAPI WlanHostedNetworkForceStart(
  _In_        HANDLE hClientHandle,
  _Out_opt_   PWLAN_HOSTED_NETWORK_REASON pFailReason,
  _Reserved_  PVOID pvReserved
);
DWORD WINAPI WlanHostedNetworkForceStop(
  _In_        HANDLE hClientHandle,
  _Out_opt_   PWLAN_HOSTED_NETWORK_REASON pFailReason,
  _Reserved_  PVOID pvReserved
);
 
 

 
参数的含义很直观,这里不再做更多地解释。值得注意的是,如果用StartUsing或者StopUsing版本的函数时,如果有客户端连接到了AP,调用WlanHostedNetworkStopUsing并不能立即停止Soft AP,而要等到客户端主动断开连接后,Soft AP才会停止。如果调用带Force的函数版本,则会强制停止Soft AP,不管是否有客户端正在连接到该AP上。当然,调用带Force的函数版本需要程序以管理员方式启动。
示例代码:
 

 代码如下 复制代码
dwReturnValue = WlanHostedNetworkStartUsing(m_hWlanClient, &dwFailedReason, NULL);   
    if(ERROR_SUCCESS != dwReturnValue)
    {
        if (wlan_hosted_network_reason_interface_unavailable == dwFailedReason)
        {
            return 0;
        }
        return -1;
    }
dwReturnValue = WlanHostedNetworkStopUsing(m_hWlanClient, &dwFailedReason, NULL);
    if (ERROR_SUCCESS != dwReturnValue)
    {
        return -1;
    }
 

启动Soft AP后,绑定Ip需要一定的时间,一般为2-3秒。Ip地址一般为192.168.173.1(也有可能是192.168.137.1).
 
调试程序时,可使用命令行方式使用Soft AP(管理员方式打开cmd):
查看当前承载网络状态 - netsh wlan show hostednetwork
配置承载网络属性,如SSID,密码等 - netsh wlan set hostednetwork ssid=***** key=***** mode=allow|disallow  (星号部分为ascii字符,key必须在8-63个字符之间)
启动承载网络 - netsh wlan start hostednetwork
关闭承载网络 - netsh wlan stop hostednetwork

时间: 2024-09-20 00:19:16

c++中Soft AP (HostedNetwork / 承载网络) 功能的相关文章

Win7如何停止无线热点AP 承载网络功能

1. 单击屏幕左下角的[开始]菜单.    2. 在搜索中输入"cmd",使用鼠标右键点击上方出现的[cmd]程序,选择[以管理员身份运行].      3. 此时会打开管理员命令提示符窗口,如下图:    1. 在命令提示符中输入"netshwlan stop hostednetwork".    2.输入后按[Enter]键确认,此时会提示"已停止承载网络".     

Win8无线网卡的承载网络功能处于不可用状态怎么解决?

  解决方法: 我们首先打开设备管理器,出现这个问题可能是网卡适配器被禁用了的关系,选择"网络适配器"看看是不是有网卡被禁用了,点击启用就行.如果使用Win7的朋友也遇到同样的问题也可以试一试哦,方法相同. 正常的启用的"网络适配器"是下面这个状态,如图:

Win8系统中的承载网络设置

  在win8 系统中的网络共享内有内置承载的网络,但是要进行设置.可是要怎么的设置呢!现在我们一起去看看具体的操作吧! Windows 8 系统也与Windows 7系统一样,内置了网络共享的方式.下面主要看看如何设置: 1. 查看电脑是否支持网络共享 在命令提示符(打开方式看文章最后)中输入:netsh wlan show drivers,然后回车.如下: 找到"支持的承载网络"一项,如果后面显示的是"是",恭喜你,你的电脑支持承载网络可以共享,否则,就另想他法

为什么软件定义网络在网络功能虚拟化中很重要?

在企业中,SDN 用于虚拟化路由和交换过程,但尚不清楚运营商是否希望或需要在其网络内使用此功能.从数据中心的角度来说,将网络控制器交由协调器管理是合适的.但对于运营商网络,以动态方式将网络作为整体进行控制比按元件控制更加重要.   NFV方案 SDN是NFV的推动力量.对于这一点,举例说明最易于理解. 以我们从中运行虚拟化宽带远程访问服务器 (BRAS) 的 NFV 方案为例.在运营商网络中,这通常是网络边缘的路由器,它会接收来自终端用户的所有通信,并使该用户可以访问因特网及其他服务.在这一简单

“无法启动承载网络连到系统上的设备没有发挥作用”怎么办

  [背景介绍] 我用的电脑是Lenovo ThinkPad E420,操作系统版本为:Windows 7 家庭普通版 SP1,处理器为:英特尔酷睿 i5-2450M CPU @ 2.50GHz,内存为:4G. [期望结果] 用该笔记本的无线网卡作为 无线路由器(即 实现wifi功能),便于没有当前没有无线路由器的环境下能够共享网络,同时上网. [操作方法] 在"开始"按钮的"搜索程序和文件"栏输入 cmd ,然后右键显示出来的 "cmd程序"并

手机通过Win7使用承载网络共享上网的方法

故障现象: 使用计算机共享有线网络供安卓或iOS系统智能手机上网使用 解决方案: 手机通过Win7系统使用承载网络共享上网的方法及常见问题处理方法 测试平台:win7 系统,联想A60手机.非联想安卓手机各一部(系统版本2.3.5 2.3.7),iphone,nokia e72i(s60 v3 系统) 提示:文章中有下划线的内容是当操作中出现问题时候需要进行的设置,如果操作顺利请跳过执行下一步. 1. 开始--所有程序--附件--命令提示符点击右键选择以管理员身份运行 2. 设置ssid和密码

Win8系统如何使用承载网络方式?

  1. 首先确认无线网卡开关开启,驱动程序已成功安装,无线网络功能可正常使用. 打开 控制面板---查看网络状态和任务,点击左侧的"更改适配器设置",确认这里有"Wi-Fi"网络连接.如下图所示: 在桌面"计算机"图标右击选择"设置",点击"设备管理器",或直接按"Windows"键和"X"键,选择"设备管理器",确认"网络适配器&qu

Windiws 8系统如何使用承载网络方式共享无线实现手机上网

  操作步骤: 1. 首先确认无线网卡开关开启,驱动程序已成功安装,无线网络功能可正常使用. 打开控制面板--查看网络状态和任务,点击左侧的"更改适配器设置",确认这里有"Wi-Fi"网络连接.如下图所示: 在桌面"计算机"图标右击选择"设置",点击"设备管理器",或直接按"windows"键和"X"键,选择"设备管理器",确认"网络适配

Win8系统如何使用承载网络方式共享无线实现手机上网

1. 首先确认无线网卡开关开启,驱动程序已成功安装,无线网络功能可正常使用. 打开 控制面板---查看网络状态和任务,点击左侧的"更改适配器设置",确认这里有"Wi-Fi"网络连接.如下图所示: 在桌面"计算机"图标右击选择"设置",点击"设备管理器",或直接按"Windows"键和"X"键,选择"设备管理器",确认"网络适配器"