从Windows 7开始,微软在操作系统中加入的Soft AP功能,使用户能够通过无线网卡,开启虚拟AP,从而实现网络共享。Soft AP又称HostedNetwork(承载网络),在Windows SDK中,提供了相应的API,以WlanHostedNetwork***开头的一系列函数。

要编码实现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原形如下:

1 DWORD WINAPI WlanOpenHandle(
2 _In_ DWORD dwClientVersion,
3 _Reserved_ PVOID pReserved,
4 _Out_ PDWORD pdwNegotiatedVersion,
5 _Out_ PHANDLE phClientHandle
6 );

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

     DWORD dwError = ;
DWORD dwServiceVersion = ;
HANDLE hClient = NULL; if (ERROR_SUCCESS != (dwError = WlanOpenHandle(
WLAN_API_VERSION,
NULL, // reserved
&dwServiceVersion,
&hClient
)))
{
return -;
} // 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 -;
} // 设置承载网络的SSID和最大连接数
WLAN_HOSTED_NETWORK_CONNECTION_SETTINGS wlanConnectionSetting;
memset(&wlanConnectionSetting, , sizeof(WLAN_HOSTED_NETWORK_CONNECTION_SETTINGS)); // WLAN_HOSTED_NETWORK_CONNECTION_SETTINGS中的SSID字段必须为ANSI类型,因此如果程序使用的是Unicode,则需要做转换。
#ifdef _UNICODE
WideCharToMultiByte(CP_ACP,
,
strSSID.GetBuffer(), // 保存SSID的CString类型
strSSID.GetLength(), // SSID字符串的长度
(LPSTR)wlanConnectionSetting.hostedNetworkSSID.ucSSID,
,
NULL,
NULL);
#else
memcpy(wlanConnectionSetting.hostedNetworkSSID.ucSSID, strSSID.GetBuffer(), strlen(strSSID.GetBuffer()));
#endif wlanConnectionSetting.hostedNetworkSSID.uSSIDLength = strlen((const char*)wlanConnectionSetting.hostedNetworkSSID.ucSSID);
wlanConnectionSetting.dwMaxNumberOfPeers = ; dwReturnValue = WlanHostedNetworkSetProperty(m_hWlanClient,
wlan_hosted_network_opcode_connection_settings,
sizeof(WLAN_HOSTED_NETWORK_CONNECTION_SETTINGS),
&wlanConnectionSetting,
&dwFailedReason,
NULL);
if(ERROR_SUCCESS != dwReturnValue)
{
return -;
}

调用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是密码缓冲区的长度,密码为口令格式时,必须包括结尾的'\0'

pucKeyData如果字符串,则必须为ANSI类型,因此如果IDE环境将字符串配置为UNICODE,需要做转换,可使用WideCharToMultiByte,或者T2A,W2A宏。

bPersistent用来指示密码是否是持久的。如果不是,那么该密码只在本次启动有效;否则下次启动Soft AP依然使用本次设置的密码。

示例代码:

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

启动或者停止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 ;
}
return -;
} dwReturnValue = WlanHostedNetworkStopUsing(m_hWlanClient, &dwFailedReason, NULL);
if (ERROR_SUCCESS != dwReturnValue)
{
return -;
}

启动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

如果本文对你有帮助,可以考虑捐赠以支持作者。

比特币地址:   1NPXhyv9W1tcqQc8iiSgx4YyPYbfoLSVzf

莱特币地址:   LSXEAZt67sdpBjZ7yhvTpPUjy6hZKivYph

Visual C++ 编程实现Soft AP (HostedNetwork / 承载网络) 功能的更多相关文章

  1. 【分享】 高级Visual Basic 编程 清晰pdf+随书源代码光盘

    搞vb6的可能不多,博客园也大多是.net java,近日在网上找到这本好书,想要成为vb高手,这本书不要错过,学完你会发现win32下,vb6还真是无所不能.可贵的是本书的作者是当时vb6 IDE的 ...

  2. 利用airbase-ng建立Soft AP

    利用airbase-ng建立Soft AP,再利用一些常见工具进行嗅探,或对抓包进行分析是出现比较早的一种MITM攻击方法.网上有很多关于手动实现的文章,也有一些自动实现脚本.这些脚本通常分两类,一类 ...

  3. 转载(略有修改):Windows 8的承载网络设置方法(w8 创建无线网络/ap)

    第一步.查看电脑是否支持网络共享 在命令提示符(打开方式看文章最后)中输入:netsh wlan show drivers,然后回车. 找到"支持的承载网络"一项,如果后面显示的是 ...

  4. 在Ubuntu中开启Soft AP功能

    在Ubuntu中开启Soft AP功能 1.查看采用的无线网卡是否支持Soft AP: 注意,可以看到有AP字样,表明支持.楼主比较背,在易迅上挑了个销量最高的netcore nw360,结果无法搭建 ...

  5. 用shell脚本实现linux系统上wifi模式(STA和soft AP)的转换

    转载请注明出处:http://blog.csdn.net/hellomxj1/ 功能:在linux系统上实现wifi STA与AP功能的转换 实现成果:1.加入wifipassword账户add_wi ...

  6. Win8开虚拟wifi ‘无法启动承载网络 组或资源的状态不是执行请求操作的正确状态“

    第一步,首先我们点开开始按钮菜单,要右键以“管理员身份”打开CMD“命令提示符”并键入或者复制(粘贴)命令:netsh wlan show drivers 查看本机无线网卡是否支持此项Wifi热点共享 ...

  7. bat文件编写(无线承载网络设置)

    就弄个例子,自己看执行效果,然后模仿写就行. 1)获取当前时间: @echo off set YEAR=%date:~0,4% set MONTH=%date:~5,2% set DAY=%date: ...

  8. WIN7建立wifi热点及无法启动承载网络的解决办法

    1,根据网络共享的方法,最简单莫过于利用Win7的虚拟网卡来做热点,而不用借助其他软件.         首先,用管理员身份打开CMD命令提示符,输入 netsh wlan set hostednet ...

  9. Win7设置承载网络 分类: 网络 2014-10-30 09:08 105人阅读 评论(0) 收藏

    Win7设置承载网络 (1)最重要的第一步,要知道自己的网卡是否支持承载网络,如果不支持就悲剧地一票否决了,支持的话才能开始以后各步骤的设置. netsh wlan show drivers (2)设 ...

随机推荐

  1. 再也不用担心ie下console.log报错了。。。

    习惯了在ff或者chrome下暴力调试的你会不会忘记注释掉而在ie下报错呢,那么可以加这个代码: if (typeof console == "undefined") { this ...

  2. Boost库

    2014-08-31 Boost库是一个经过千锤百炼.可移植.提供源代码的C++库,作为标准库的后备,是C++标准化进程的发动机之一.Boost库由C++标准委员会库工作组成员发起,其中有些内容有望成 ...

  3. jQuery dataTables 网格

    对于服务器来说,可以通过请求参数来获得当前的操作信息. 类型 名称 说明 int iDisplayStart 显示的起始索引 int iDisplayLength 显示的行数 int iColumns ...

  4. python爬虫学习(3)_模拟登陆

    1.登陆超星慕课,chrome抓包,模拟header,提取表单隐藏元素构成params. 主要是验证码图片地址,在js中发现由js->new Date().getTime()时间戳动态生成url ...

  5. 记录:Ubuntu下配置Eclipse

    >>下载Eclipse. 下载链接:http://www.eclipse.org/downloads/ 我选择了64bit的版本 >>安装Eclipse. 解压文件: tar ...

  6. centos防火墙操作

    centos防火墙基本操作 #/sbin/iptables -I INPUT -p tcp --dport 80 -j ACCEPT#/sbin/iptables -I INPUT -p tcp -- ...

  7. sql server 分组统计数据

    说明:group by是sql中对数据表中的数据进行分组的,在select列表中出现的字段必须全部出现在group by 字段中,出现在聚合函数中的字段在group by中可有可无,没有出现在sele ...

  8. 【MongoDB】The Access control of mongodb

    In this blog we mainly talk about the access control including limitation of ip, setting listen port ...

  9. 服务器后端开发系列——《实战FastDFS分布式文件系统》[转]

    1.FastDFS的配置.部署与API使用解读(1)Get Started with FastDFS 内容:讲解FastDFS的背景.基本原理,并讲述基本的配置.部署和测试的内容. 2.FastDFS ...

  10. SQL高级优化之经常使用的优化策略-2(The Return Of The King)

    1.2 索引 索引不是越多越好,你须要知道索引建立多了.写入数据的效率会减少.怎样使用索引要看你的项目的应用场景,做出合理的測试评估. 1.2.1 统计数量 统计数量上.假设字段(fieldName) ...