从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. js 打印网页指定内容

    function doPrint() { setTimeout(function() { bdhtml=window.document.body.innerHTML; sprnstr="&l ...

  2. etc下

    用户账号与密码参数:  /etc/passwd  .  /etc/shadow 用户组相关方面的条件:     /etc/group   .   /etc/gshadow 用户个人文件数据:   /h ...

  3. hdoj 2035 人见人爱A^B

    人见人爱A^B Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Sub ...

  4. Oracle 的 VKTM 进程 - virtual keeper of time

    在Oracle Database 11g中,VKTM是一个新增的后台进程.这个进程的含义是: VKTM (virtual keeper of time) is responsible for prov ...

  5. Python自动化之session

    request.body 所有请求内容的原生数据 request.META 所有请求头的原生数据 cookie返回存在于响应头里面 session session是保存在服务端的键值对 cookie和 ...

  6. 加速 Gradle 构建大型 Android 项目的方法[转]

    加速 Gradle 构建大型 Android 项目的方法 时间 2016-03-14 20:38:00  Mystra 原文  http://www.wangchenlong.org/2016/03/ ...

  7. At-rule | CSS @ 规则

    译自:MDN(Mozilla开发者网络) At-rule 一.什么是at-rules eg:@charset "utf-8"; at-rule 是CSS样式声明,以@开头,紧跟着是 ...

  8. 格式化日期时间字符串 Get-Date -Uformat , -format

    #将字符串格式化为时间格式 $dateTimeStr = '20141231T23:59:59' $format = 'yyyyMMddTHH:mm:ss' $formatProvider = [Gl ...

  9. 【剑指Offer学习】【面试题40:数组中仅仅出现一次的数字】

    题目:一个整型数组里除了两个数字之外.其它的数字都出现了两次,请敲代码找出这两个仅仅出现一次的数字. 要求时间复杂度是O(n),空间复杂度是O(1). 举例说明 比如输入数组{2, 4, 3, 6, ...

  10. MVC中一般为什么用IQueryable而不是用IList

    IList(IList<T>)会立即在内存里创建持久数据,这就没有实现“延期执行(deferred execution)”,如果被加载的实体有关联实体(associations),此关联实 ...