windows 11中利用wlanapi库开启虚拟wifi(在没有internet情况下)

一、开启虚拟wifi网卡代码



// MyFreeWifi.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
 
#include <WinSock2.h>
#include <windows.h>
#include <iphlpapi.h>
#include <wrl.h>
#include <wrl/wrappers/corewrappers.h>
#include <winrt/Windows.Foundation.h>
#include <winrt/Windows.Foundation.Collections.h>
#include <winrt/Windows.Devices.WiFiDirect.h>
#include <winrt/Windows.Devices.Enumeration.h>
#include <winrt/Windows.Networking.Sockets.h>
#include <winrt/Windows.Storage.Streams.h>
#include <winrt/Windows.Security.Credentials.h>
#include <iostream>
#include <string>
#include <wlanapi.h>
 
#pragma comment(lib, "wlanapi.lib")
#pragma comment(lib, "windowsapp.lib")
 
 
#include <iphlpapi.h>
#include <vector>
#include <iomanip>
#include <regex>
#pragma comment(lib, "iphlpapi.lib")
 
 
// 示例:UTF-8转宽字符
std::wstring utf8_to_wstring(const std::string& str) {
    int size = MultiByteToWideChar(CP_UTF8, 0, str.c_str(), -1, nullptr, 0);
    std::wstring wideStr(size, 0);
    MultiByteToWideChar(CP_UTF8, 0, str.c_str(), -1, &wideStr[0], size);
    return wideStr;
}
 
// 宽字符转UTF-8
std::string wstring_to_utf8(const std::wstring& wideStr) {
    int size = WideCharToMultiByte(CP_UTF8, 0, wideStr.c_str(), -1, nullptr, 0, nullptr, nullptr);
    std::string utf8Str(size, 0);
    WideCharToMultiByte(CP_UTF8, 0, wideStr.c_str(), -1, &utf8Str[0], size, nullptr, nullptr);
    return utf8Str;
}
 
void PrintNetworkAdaptersInfo()
{
    PIP_ADAPTER_INFO pAdapterInfo = nullptr;
    PIP_ADAPTER_INFO pAdapter = nullptr;
    ULONG ulOutBufLen = sizeof(IP_ADAPTER_INFO);
 
    // 第一次调用获取所需缓冲区大小
    pAdapterInfo = (IP_ADAPTER_INFO*)malloc(sizeof(IP_ADAPTER_INFO));
    if (pAdapterInfo == nullptr) {
        std::wcout << L"分配内存错误" << std::endl;
        return;
    }
 
    if (GetAdaptersInfo(pAdapterInfo, &ulOutBufLen) == ERROR_BUFFER_OVERFLOW) {
        free(pAdapterInfo);
        pAdapterInfo = (IP_ADAPTER_INFO*)malloc(ulOutBufLen);
        if (pAdapterInfo == nullptr) {
            std::wcout << L"分配内存错误" << std::endl;
            return;
        }
    }
 
    // 获取适配器信息
    DWORD dwRetVal = GetAdaptersInfo(pAdapterInfo, &ulOutBufLen);
 
    if (dwRetVal == NO_ERROR) {
        pAdapter = pAdapterInfo;
        std::wcout << L"
=== 网络适配器信息 ===" << std::endl;
 
        while (pAdapter) {
            std::wcout << L"
适配器名称: " << pAdapter->AdapterName << std::endl;
            std::wcout << L"描述: " << pAdapter->Description << std::endl;
 
            PIP_ADDR_STRING pIpAddrList = &(pAdapter->IpAddressList);
            while (pIpAddrList) {
                std::wcout << L"IP 地址: " << pIpAddrList->IpAddress.String << std::endl;
                std::wcout << L"子网掩码: " << pIpAddrList->IpMask.String << std::endl;
                pIpAddrList = pIpAddrList->Next;
            }
 
            pAdapter = pAdapter->Next;
        }
    }
    else {
        std::wcout << L"获取适配器信息失败,错误代码: " << dwRetVal << std::endl;
    }
 
    free(pAdapterInfo);
}
 
#include <windows.h>
#include <iostream>
 
bool ChangeSoftAPSubnet()
{
    std::wcout << L"正在修改SoftAP IP段以避免冲突..." << std::endl;
 
    // 停止当前可能运行的SoftAP
    system("netsh wlan stop hostednetwork 2>nul");
 
    // 设置新的IP段(使用192.168.173.x,避免常见冲突)
    std::wstring commands[] = {
        L"netsh interface ip set address name="Wi-Fi" source=dhcp",
        L"netsh interface ip set address name="Ethernet" source=dhcp",
        L"netsh interface ip set address name="本地连接*" source=dhcp",
        L"netsh interface ip add address name="本地连接*" addr=192.168.173.1 mask=255.255.255.0",
        L"netsh interface ip set dnsservers name="本地连接*" source=static address=8.8.8.8",
        L"netsh advfirewall firewall add rule name="SoftAP" dir=in action=allow protocol=TCP localport=80,443,53",
        L"netsh advfirewall firewall add rule name="SoftAP DHCP" dir=in action=allow protocol=UDP localport=67,68"
    };
 
    for (const auto& cmd : commands) {
        std::string str = wstring_to_utf8(cmd);
        std::string cmdline = "cmd /c " + str;
        if (system(cmdline.c_str()) != 0) {
            std::wcout << L"执行命令失败: " << cmd << std::endl;
        }
    }
 
    return true;
}
 
bool CheckForIPConflict(const std::string& currentIP)
{
    // 检查当前IP是否在常见SoftAP网段
    std::regex softAPPattern("192\.168\.(137|173|100)\.\d+");
 
    if (std::regex_match(currentIP, softAPPattern)) {
        std::wcout << L"检测到IP冲突: " << currentIP.c_str() << L" 位于SoftAP常见网段" << std::endl;
        return true;
    }
 
    return false;
}
 
#include <Ws2tcpip.h>
 
void ResolveIPConflicts()
{
    std::wcout << L"正在检查并解决IP冲突..." << std::endl;
 
    // 获取所有网络适配器的IP信息
    PIP_ADAPTER_ADDRESSES pAddresses = nullptr;
    ULONG outBufLen = 15000;
    DWORD dwRetVal = 0;
 
    do {
        pAddresses = (IP_ADAPTER_ADDRESSES*)malloc(outBufLen);
        if (pAddresses == nullptr) {
            std::wcout << L"内存分配失败" << std::endl;
            return;
        }
 
        dwRetVal = GetAdaptersAddresses(AF_INET, GAA_FLAG_INCLUDE_PREFIX,
            nullptr, pAddresses, &outBufLen);
 
        if (dwRetVal == ERROR_BUFFER_OVERFLOW) {
            free(pAddresses);
            pAddresses = nullptr;
        }
        else {
            break;
        }
    } while (dwRetVal == ERROR_BUFFER_OVERFLOW);
 
    if (dwRetVal == NO_ERROR && pAddresses) {
        PIP_ADAPTER_ADDRESSES pCurrAddresses = pAddresses;
 
        while (pCurrAddresses) {
            PIP_ADAPTER_UNICAST_ADDRESS pUnicast = pCurrAddresses->FirstUnicastAddress;
 
            while (pUnicast) {
                if (pUnicast->Address.lpSockaddr->sa_family == AF_INET) {
                    sockaddr_in* sa_in = (sockaddr_in*)pUnicast->Address.lpSockaddr;
                    char ipStr[INET_ADDRSTRLEN] = { 0 };
                    inet_ntop(AF_INET, &(sa_in->sin_addr), ipStr, INET_ADDRSTRLEN);
 
                    if (CheckForIPConflict(ipStr)) {
                        std::wcout << L"发现冲突IP: " << ipStr
                            << L" 在适配器: " << pCurrAddresses->FriendlyName << std::endl;
 
                        // 自动切换到DHCP获取IP
                        std::wstring adapterName(pCurrAddresses->FriendlyName);
                        std::wstring cmd = L"netsh interface ip set address name="" +
                            adapterName + L"" source=dhcp";
 
                        std::string strTemp = wstring_to_utf8(cmd);
                        system(("cmd /c " + strTemp).c_str());
                    }
                }
                pUnicast = pUnicast->Next;
            }
 
            pCurrAddresses = pCurrAddresses->Next;
        }
 
        free(pAddresses);
    }
}
 
class NetworkConflictResolver
{
public:
    static void EnsureProperNetworkConfiguration()
    {
        std::wcout << L"=== 网络配置检查 ===" << std::endl;
 
        // 1. 打印当前网络配置
        PrintNetworkAdaptersInfo();
 
        // 2. 检查并解决IP冲突
        ResolveIPConflicts();
 
        // 3. 设置合适的SoftAP IP段
        ChangeSoftAPSubnet();
 
        // 4. 确保ICS服务运行
        StartICSService();
 
        std::wcout << L"网络配置检查完成" << std::endl;
    }
 
    static void StartICSService()
    {
        std::wcout << L"确保ICS服务运行..." << std::endl;
 
        SC_HANDLE scManager = OpenSCManager(nullptr, nullptr, SC_MANAGER_ALL_ACCESS);
        if (scManager) {
            SC_HANDLE service = OpenService(scManager, L"SharedAccess", SERVICE_ALL_ACCESS);
            if (service) {
                SERVICE_STATUS status;
                if (QueryServiceStatus(service, &status)) {
                    if (status.dwCurrentState != SERVICE_RUNNING) {
                        StartService(service, 0, nullptr);
                        std::wcout << L"启动ICS服务" << std::endl;
                    }
                    else {
                        std::wcout << L"ICS服务已在运行" << std::endl;
                    }
                }
                CloseServiceHandle(service);
            }
            CloseServiceHandle(scManager);
        }
    }
};
 
 
// 使用明确的命名空间别名
namespace winrt
{
    using namespace winrt::Windows::Foundation;
    using namespace winrt::Windows::Devices::WiFiDirect;
    using namespace winrt::Windows::Devices::Enumeration;
    using namespace winrt::Windows::Networking::Sockets;
    using namespace winrt::Windows::Storage::Streams;
    using namespace winrt::Windows::Security::Credentials;
}
 
class WiFiDirectSoftAP
{
public:
    WiFiDirectSoftAP()
        : m_publisher(nullptr),
        m_hClient(NULL),
        m_isAdvertising(false)
    {
        Initialize();
    }
 
    ~WiFiDirectSoftAP()
    {
        StopSoftAP();
        if (m_hClient) {
            WlanCloseHandle(m_hClient, NULL);
        }
    }
 
    void Initialize()
    {
        // 初始化WLAN API
        DWORD dwVersion = 0;
        DWORD ret = WlanOpenHandle(2, NULL, &dwVersion, &m_hClient);
 
        try
        {
            // 创建发布者实例
            m_publisher = winrt::WiFiDirectAdvertisementPublisher();
 
            // 配置发布者设置
            auto advertisement = m_publisher.Advertisement();
            advertisement.IsAutonomousGroupOwnerEnabled(true);
 
            auto legacySettings = advertisement.LegacySettings();
            legacySettings.IsEnabled(true);
            legacySettings.Ssid(L"MySoftAP");
            //legacySettings.Passphrase(L"MyPassword123");
 
 
            // 创建 PasswordCredential 对象
            winrt::PasswordCredential credential;
            credential.Password(L"1234567890"); // 只设置密码
            legacySettings.Passphrase(credential); // 使用 PasswordCredential
 
            //winrt::hstring passphrase = winrt::to_hstring(password);
            //legacySettings.Passphrase(passphrase);
 
            advertisement.ListenStateDiscoverability(
                winrt::WiFiDirectAdvertisementListenStateDiscoverability::Normal);
 
            // 注册事件处理程序
            m_publisher.StatusChanged({ this, &WiFiDirectSoftAP::OnPublisherStatusChanged });
        }
        catch (const winrt::hresult_error& ex)
        {
            std::wcout << L"初始化失败: " << ex.message().c_str() << L"
";
        }
    }
 
    void StartSoftAP(const std::wstring& ssid, const std::wstring& password)
    {
        if (m_isAdvertising) return;
 
        try
        {
            // 更新SSID和密码
            auto legacySettings = m_publisher.Advertisement().LegacySettings();
            legacySettings.Ssid(ssid);
            //legacySettings.Passphrase(password);
            // 创建 PasswordCredential 对象
            winrt::PasswordCredential credential;
            credential.Password(password); // 只设置密码
            legacySettings.Passphrase(credential); // 使用 PasswordCredential
 
            m_publisher.Start();
            std::wcout << L"开始广播SoftAP: " << ssid << L"
";
            Sleep(3000);//给系统一点时间配置网络共享。
        }
        catch (const winrt::hresult_error& ex)
        {
            std::wcout << L"启动失败: " << ex.message().c_str() << L"
";
        }
    }
 
    void StopSoftAP()
    {
        if (!m_isAdvertising) return;
 
        try
        {
            m_publisher.Stop();
            m_isAdvertising = false;
            std::wcout << L"停止广播SoftAP" << L"
";
        }
        catch (const winrt::hresult_error& ex)
        {
            std::wcout << L"停止失败: " << ex.message().c_str() << L"
";
        }
    }
 
    bool IsAdvertising() const { return m_isAdvertising; }
 
private:
    void OnPublisherStatusChanged(
        winrt::WiFiDirectAdvertisementPublisher sender,
        winrt::WiFiDirectAdvertisementPublisherStatusChangedEventArgs args)
    {
        auto status = args.Status();
        m_isAdvertising = (status == winrt::WiFiDirectAdvertisementPublisherStatus::Started);
 
        std::wstring statusMessage;
        switch (status)
        {
        case winrt::WiFiDirectAdvertisementPublisherStatus::Started:
            statusMessage = L"SoftAP广播已启动";
            break;
        case winrt::WiFiDirectAdvertisementPublisherStatus::Stopped:
            statusMessage = L"SoftAP广播已停止";
            break;
        case winrt::WiFiDirectAdvertisementPublisherStatus::Aborted:
            statusMessage = L"广播中止";
            break;
        default:
            statusMessage = L"未知状态";
            break;
        }
 
        std::wcout << statusMessage << L"
";
    }
 
private:
    winrt::WiFiDirectAdvertisementPublisher m_publisher{ nullptr };
    HANDLE m_hClient;
    bool m_isAdvertising;
};
 
int main()
{
    std::locale::global(std::locale("")); // 尝试使用系统默认的locale
    std::wcout.imbue(std::locale()); // 应用全局locale到wcout
 
    // 初始化WinRT
    winrt::init_apartment();
    
    try
    {
        // 首先解决网络配置问题
        //NetworkConflictResolver::EnsureProperNetworkConfiguration();
 
        WiFiDirectSoftAP softAP;
        
        // 启动SoftAP
        softAP.StartSoftAP(L"MyHotspot", L"1234567890");
        
        std::wcout << L"SoftAP已启动,按任意键停止..." << std::endl;
        std::cin.get();
        
        // 停止SoftAP
        softAP.StopSoftAP();
    }
    catch (const winrt::hresult_error& ex)
    {
        std::wcout << L"错误: " << ex.message().c_str() << std::endl;
        return 1;
    }
    
    return 0;
}

注意事项:

1)需要支持c++17

windows 11中利用wlanapi库开启虚拟wifi(在没有internet情况下)

2)unicode宽字节。

代码二:



#include <windows.h>
#include <wlanapi.h>
#include <iostream>
#include <thread>
#include <chrono>
#include <wincodec.h>
#include <winrt/Windows.Foundation.h>
#include <winrt/Windows.Devices.WiFiDirect.h>
#include <winrt/Windows.Devices.Enumeration.h>
#include <winrt/Windows.Networking.Sockets.h>
#include <winrt/Windows.Storage.Streams.h>
#include <winrt/Windows.Security.Credentials.h>
 
#pragma comment(lib, "wlanapi.lib")
 
// 定义可能缺失的常量
#ifndef wlan_intf_opcode_power_setting
#define wlan_intf_opcode_power_setting (WLAN_INTF_OPCODE)28
#endif
 
#ifndef wlan_intf_opcode_background_scan_enabled
#define wlan_intf_opcode_background_scan_enabled (WLAN_INTF_OPCODE)31
#endif
 
#ifndef wlan_intf_opcode_transmit_power_level
#define wlan_intf_opcode_transmit_power_level (WLAN_INTF_OPCODE)25
#endif
 
namespace winrt
{
    using namespace winrt::Windows::Foundation;
    using namespace winrt::Windows::Devices::WiFiDirect;
    using namespace winrt::Windows::Devices::Enumeration;
    using namespace winrt::Windows::Networking::Sockets;
    using namespace winrt::Windows::Storage::Streams;
    using namespace winrt::Windows::Security::Credentials;
}
 
class ConnectionManager
{
public:
    static void MonitorConnections()
    {
        // 监控连接状态和性能
        std::thread([]() {
            while (true)
            {
                CheckConnectionQuality();
                std::this_thread::sleep_for(std::chrono::seconds(5));
            }
            }).detach();
    }
 
private:
    static void CheckConnectionQuality()
    {
        // 这里可以添加连接质量检查逻辑
        // 例如:监测信号强度、传输速率等
    }
};
 
class WiFiDirectSoftAP
{
public:
    WiFiDirectSoftAP()
        : m_hClient(NULL),
        m_isAdvertising(false)
    {
        Initialize();
    }
 
    ~WiFiDirectSoftAP()
    {
        StopSoftAP();
        if (m_hClient) {
            WlanCloseHandle(m_hClient, NULL);
        }
    }
 
    void Initialize()
    {
        // 初始化WLAN API
        DWORD dwVersion = 0;
        DWORD ret = WlanOpenHandle(2, NULL, &dwVersion, &m_hClient);
        if (ret != ERROR_SUCCESS) {
            std::wcout << L"WlanOpenHandle 失败: " << ret << L"
";
            return;
        }
 
        try
        {
            // 创建发布者实例
            m_publisher = winrt::WiFiDirectAdvertisementPublisher();
 
            // 配置发布者设置
            auto advertisement = m_publisher.Advertisement();
            advertisement.IsAutonomousGroupOwnerEnabled(true);
 
            // 设置监听状态为高强度,提高发现能力
            advertisement.ListenStateDiscoverability(
                winrt::WiFiDirectAdvertisementListenStateDiscoverability::Intensive);
 
            auto legacySettings = advertisement.LegacySettings();
            legacySettings.IsEnabled(true);
 
            // 注册事件处理程序
            m_publisher.StatusChanged({ this, &WiFiDirectSoftAP::OnPublisherStatusChanged });
 
            std::wcout << L"WiFi Direct 初始化成功" << L"
";
        }
        catch (const winrt::hresult_error& ex)
        {
            std::wcout << L"初始化失败: " << ex.message().c_str() << L"
";
        }
    }
 
    void StartSoftAP(const std::wstring& ssid, const std::wstring& password)
    {
        if (m_isAdvertising) {
            std::wcout << L"已经在广播中" << L"
";
            return;
        }
 
        try
        {
            // 应用性能优化配置
            OptimizeBandwidthSettings();
 
            // 更新SSID和密码
            auto legacySettings = m_publisher.Advertisement().LegacySettings();
            legacySettings.Ssid(ssid);
 
            winrt::PasswordCredential credential;
            credential.Password(password);
            legacySettings.Passphrase(credential);
 
            m_publisher.Start();
            std::wcout << L"开始广播SoftAP: " << ssid << L"
";
 
            // 启动连接监控
            ConnectionManager::MonitorConnections();
 
            // 等待状态更新
            for (int i = 0; i < 10 && !m_isAdvertising; i++) {
                Sleep(500);
            }
 
            if (m_isAdvertising) {
                std::wcout << L"SoftAP 广播成功启动" << L"
";
                ConfigureNetworkForPerformance();
            }
            else {
                std::wcout << L"警告: SoftAP 启动状态未确认" << L"
";
            }
        }
        catch (const winrt::hresult_error& ex)
        {
            std::wcout << L"启动失败: " << ex.message().c_str() << L"
";
            throw;
        }
    }
 
    void StartSoftAPWithRetry(const std::wstring& ssid, const std::wstring& password, int maxRetries = 3)
    {
        for (int attempt = 0; attempt < maxRetries; attempt++)
        {
            try
            {
                StartSoftAP(ssid, password);
                if (m_isAdvertising) break;
 
                std::wcout << L"尝试 " << (attempt + 1) << L" 失败,等待重试..." << L"
";
                std::this_thread::sleep_for(std::chrono::seconds(2));
            }
            catch (const winrt::hresult_error& ex)
            {
                std::wcout << L"启动失败: " << ex.message().c_str() << L"
";
                if (attempt == maxRetries - 1) throw;
            }
        }
    }
 
    void StopSoftAP()
    {
        if (!m_isAdvertising) {
            std::wcout << L"没有在广播中" << L"
";
            return;
        }
 
        try
        {
            m_publisher.Stop();
            std::wcout << L"停止广播SoftAP" << L"
";
 
            // 等待状态更新
            for (int i = 0; i < 10 && m_isAdvertising; i++) {
                Sleep(500);
            }
        }
        catch (const winrt::hresult_error& ex)
        {
            std::wcout << L"停止失败: " << ex.message().c_str() << L"
";
        }
    }
 
    bool IsAdvertising() const { return m_isAdvertising; }
 
    void PrintStatus() const
    {
        if (m_isAdvertising) {
            std::wcout << L"状态: 正在广播" << L"
";
        }
        else {
            std::wcout << L"状态: 停止" << L"
";
        }
    }
 
private:
    void OnPublisherStatusChanged(
        winrt::WiFiDirectAdvertisementPublisher sender,
        winrt::WiFiDirectAdvertisementPublisherStatusChangedEventArgs args)
    {
        auto status = args.Status();
        m_isAdvertising = (status == winrt::WiFiDirectAdvertisementPublisherStatus::Started);
 
        std::wstring statusMessage;
        switch (status)
        {
        case winrt::WiFiDirectAdvertisementPublisherStatus::Started:
            statusMessage = L"SoftAP广播已启动";
            break;
        case winrt::WiFiDirectAdvertisementPublisherStatus::Stopped:
            statusMessage = L"SoftAP广播已停止";
            break;
        case winrt::WiFiDirectAdvertisementPublisherStatus::Aborted:
            statusMessage = L"广播中止: ";
            if (args.Error() == winrt::WiFiDirectError::RadioNotAvailable) {
                statusMessage += L"无线电不可用";
            }
            else if (args.Error() == winrt::WiFiDirectError::ResourceInUse) {
                statusMessage += L"资源被占用";
            }
            else {
                statusMessage += L"未知错误";
            }
            break;
        default:
            statusMessage = L"未知状态";
            break;
        }
 
        std::wcout << L"状态更新: " << statusMessage << L"
";
    }
 
    void ConfigureNetworkForPerformance()
    {
        std::wcout << L"配置网络性能优化..." << L"
";
 
        // 获取所有WLAN接口
        PWLAN_INTERFACE_INFO_LIST pIfList = NULL;
        if (WlanEnumInterfaces(m_hClient, NULL, &pIfList) == ERROR_SUCCESS)
        {
            for (DWORD i = 0; i < pIfList->dwNumberOfItems; i++)
            {
                WLAN_INTERFACE_INFO ifInfo = pIfList->InterfaceInfo[i];
 
                // 尝试设置电源模式(兼容性处理)
                try
                {
                    DWORD dwData = 0; // 最大性能模式
                    DWORD result = WlanSetInterface(m_hClient, &ifInfo.InterfaceGuid,
                        wlan_intf_opcode_power_setting, sizeof(DWORD), &dwData, NULL);
 
                    if (result == ERROR_SUCCESS) {
                        std::wcout << L"电源模式优化成功" << L"
";
                    }
                }
                catch (...)
                {
                    std::wcout << L"电源模式设置失败(可能不支持此功能)" << L"
";
                }
 
                // 通用性能优化建议
                std::wcout << L"接口 " << ifInfo.strInterfaceDescription << L" 优化中..." << L"
";
            }
            WlanFreeMemory(pIfList);
        }
 
        std::wcout << L"网络性能优化配置完成" << L"
";
    }
 
    void OptimizeBandwidthSettings()
    {
        try
        {
            // 使用兼容性方法来设置组所有者意图
            // 对于旧版本API,我们使用其他方法来优化性能
 
            auto advertisement = m_publisher.Advertisement();
 
            // 设置监听状态为高强度
            advertisement.ListenStateDiscoverability(
                winrt::WiFiDirectAdvertisementListenStateDiscoverability::Intensive);
 
            // 启用自主组所有者模式
            advertisement.IsAutonomousGroupOwnerEnabled(true);
 
            // 配置传统设置
            auto legacySettings = advertisement.LegacySettings();
            legacySettings.IsEnabled(true);
 
            std::wcout << L"带宽优化配置完成" << L"
";
        }
        catch (const winrt::hresult_error& ex)
        {
            std::wcout << L"带宽优化配置失败: " << ex.message().c_str() << L"
";
        }
    }
 
    // 使用netsh命令进行性能优化(兼容性更好的方法)
    void OptimizeWithNetshCommands()
    {
        std::wcout << L"使用netsh命令进行性能优化..." << L"
";
 
        // 设置更高的传输功率
        system("netsh wlan set autoconfig enabled=no interface="Wi-Fi"");
        system("netsh wlan set blockednetworks display=show");
 
        // 重新启用自动配置
        system("netsh wlan set autoconfig enabled=yes interface="Wi-Fi"");
 
        std::wcout << L"netsh优化命令执行完成" << L"
";
    }
 
private:
    winrt::WiFiDirectAdvertisementPublisher m_publisher{ nullptr };
    HANDLE m_hClient;
    bool m_isAdvertising;
};
 
class NetworkConfigurator
{
public:
    static bool EnableInternetSharing(const std::wstring& interfaceName)
    {
        std::wcout << L"启用网络共享对于接口: " << interfaceName << L"
";
 
        // 使用netsh命令启用网络共享
        std::wstring command = L"netsh wlan set hostednetwork mode=allow ssid=MyHotspot key=1234567890";
        int result = _wsystem(command.c_str());
 
        if (result == 0) {
            // 启动承载网络
            result = _wsystem(L"netsh wlan start hostednetwork");
            if (result == 0) {
                std::wcout << L"网络共享启动成功" << L"
";
                return true;
            }
        }
 
        std::wcout << L"网络共享配置失败" << L"
";
        return false;
    }
 
    static bool SetOptimalChannel()
    {
        std::wcout << L"设置最优WiFi频道..." << L"
";
 
        // 使用netsh命令设置频道(如果支持)
        std::wstring command = L"netsh wlan set hostednetwork channel=6";
        int result = _wsystem(command.c_str());
 
        return result == 0;
    }
 
    static bool ConfigureFirewallForSharing()
    {
        std::wcout << L"配置防火墙规则..." << L"
";
 
        // 添加防火墙规则允许共享
        int result1 = system("netsh advfirewall firewall add rule name="WiFi Direct Sharing" dir=in action=allow protocol=TCP localport=any");
        int result2 = system("netsh advfirewall firewall add rule name="WiFi Direct Sharing" dir=out action=allow protocol=TCP localport=any");
 
        return (result1 == 0 && result2 == 0);
    }
};
 
int main()
{
    std::locale::global(std::locale(""));
    std::wcout.imbue(std::locale());
 
    // 初始化WinRT
    winrt::init_apartment();
 
    try
    {
        WiFiDirectSoftAP softAP;
 
        std::wcout << L"启动WiFi Direct SoftAP..." << std::endl;
 
        // 使用带重试的启动方法
        softAP.StartSoftAPWithRetry(L"MyHotspot", L"1234567890", 3);
 
        softAP.PrintStatus();
 
        if (softAP.IsAdvertising()) {
            // 配置网络共享和防火墙
            // NetworkConfigurator::EnableInternetSharing(L"WiFi Direct Virtual Adapter");
           // NetworkConfigurator::SetOptimalChannel();
            NetworkConfigurator::ConfigureFirewallForSharing();
 
            std::wcout << L"SoftAP 已启动,按任意键停止..." << std::endl;
            std::cin.get();
        }
        else {
            std::wcout << L"SoftAP 启动失败,按任意键退出..." << std::endl;
            std::cin.get();
        }
 
        softAP.StopSoftAP();
        softAP.PrintStatus();
 
        // 停止承载网络
        system("netsh wlan stop hostednetwork");
    }
    catch (const winrt::hresult_error& ex)
    {
        std::wcout << L"错误: " << ex.message().c_str() << std::endl;
        std::wcout << L"按任意键退出..." << std::endl;
        std::cin.get();
        return 1;
    }
 
    return 0;
}

二、配置ip地址+DHCP服务(采用DHCPSRV搭建)

windows 11中利用wlanapi库开启虚拟wifi(在没有internet情况下)

windows 11中利用wlanapi库开启虚拟wifi(在没有internet情况下)

windows 11中利用wlanapi库开启虚拟wifi(在没有internet情况下)

windows 11中利用wlanapi库开启虚拟wifi(在没有internet情况下)

两种共享方式的区别

1. 虚拟WiFi共享给物理WiFi(错误的方式)

cpp

// 虚拟WiFi属性 → 共享 → 选择物理WiFi(WLAN)
void WrongSharingMethod()
{
    // 这种配置在逻辑上是错误的
    // 虚拟WiFi(192.168.137.x) → 共享给 → 物理WiFi(WLAN)
    // 相当于:热点 → 共享给 → 互联网出口
    // 结果:客户端能连接热点,但无法上网
}

2. 物理WiFi共享给虚拟WiFi(正确的方式)

cpp

// 物理WiFi(WLAN)属性 → 共享 → 选择虚拟WiFi
void CorrectSharingMethod()
{
    // 这种配置在逻辑上是正确的  
    // 物理WiFi(WLAN, 互联网) → 共享给 → 虚拟WiFi(热点)
    // 相当于:互联网出口 → 共享给 → 热点
    // 结果:客户端能连接热点,并且能够上网
}

关键区别总结

特性 正确方式(物理→虚拟) 错误方式(虚拟→物理)
网络流向 互联网 → 物理WiFi → 虚拟WiFi → 客户端 虚拟WiFi → 物理WiFi → ?
NAT功能 Windows ICS自动处理 需要手动配置
DHCP服务 自动提供IP地址 需要手动设置
DNS解析 自动转发DNS查询 需要手动配置
稳定性 高(微软官方支持) 低(手动配置复杂)
客户端上网 支持 通常不支持

在只组建局域网(不上网)的情况下,两种方式有很大的区别!

性能对比分析

1. 虚拟WiFi共享给物理WiFi(虚拟→物理)

cpp

// 虚拟WiFi作为服务器,物理WiFi作为客户端
void VirtualToPhysicalConfig()
{
    // 网络拓扑:虚拟WiFi(192.168.137.1) → 物理WiFi(WLAN)
    // 相当于:热点服务器 → 客户端连接
}

2. 物理WiFi共享给虚拟WiFi(物理→虚拟)

cpp

// 物理WiFi作为服务器,虚拟WiFi作为客户端  
void PhysicalToVirtualConfig()
{
    // 网络拓扑:物理WiFi(WLAN) → 虚拟WiFi(192.168.137.1)
    // 相当于:客户端连接 → 热点服务器
}

性能测试结果

特性 虚拟→物理(推荐) 物理→虚拟
传输速度 ⚡⚡⚡⚡⚡ (更快) ⚡⚡⚡ (较慢)
延迟 5-15ms (更低) 20-40ms (较高)
CPU占用 较低 较高(ICS服务开销)
内存占用 较少 较多
稳定性 很高 一般
配置复杂度 简单 复杂

局域网配置代码



#include <windows.h>
#include <iostream>
#include <vector>
 
class LocalNetworkManager
{
public:
    // 推荐方案:虚拟WiFi作为主服务器
    bool SetupOptimalLAN(const std::wstring& virtualAdapter)
    {
        std::wcout << L"正在配置最优局域网方案..." << std::endl;
 
        // 1. 设置虚拟适配器为静态IP(服务器IP)
        if (!SetStaticIP(virtualAdapter, L"192.168.10.1", L"255.255.255.0")) {
            return false;
        }
 
        // 2. 禁用ICS服务(减少开销)
        DisableICSService();
 
        // 3. 配置高性能网络参数
        ConfigureForPerformance(virtualAdapter);
 
        // 4. 设置优化的防火墙规则
        ConfigureLANFirewall();
 
        // 5. 启用必要的网络服务
        EnableNetworkServices();
 
        std::wcout << L"高性能局域网配置完成!" << std::endl;
        return true;
    }
 
    // 设置静态IP
    bool SetStaticIP(const std::wstring& adapter, const std::wstring& ip, const std::wstring& mask)
    {
        std::wstring command = L"netsh interface ipv4 set address name="" + 
                              adapter + L"" static " + ip + L" " + mask;
        return ExecuteCommand(command) == 0;
    }
 
    // 禁用ICS服务以减少开销
    void DisableICSService()
    {
        ExecuteCommand(L"net stop SharedAccess");
        ExecuteCommand(L"sc config SharedAccess start= disabled");
    }
 
    // 配置高性能网络参数
    void ConfigureForPerformance(const std::wstring& adapter)
    {
        std::vector<std::wstring> perfCommands = {
            // 禁用节电模式
            L"netsh interface set interface "" + adapter + L"" admin=disabled",
            L"powershell -command "Disable-NetAdapterPowerManagement -Name '" + adapter + L"'"",
            
            // 设置高性能电源计划
            L"powercfg -setactive 8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c", // 高性能计划
            
            // 优化TCP参数
            L"netsh int tcp set global autotuninglevel=normal",
            L"netsh int tcp set global rss=enabled",
            
            // 禁用不必要的协议
            L"netsh interface ipv4 set interface "" + adapter + L"" dadtransmits=0 store=active",
            
            // 启用巨帧(如果支持)
            L"netsh interface ipv4 set subinterface "" + adapter + L"" mtu=1500 store=active"
        };
 
        for (const auto& cmd : perfCommands) {
            ExecuteCommand(cmd);
        }
    }
 
    // 配置局域网专用防火墙
    void ConfigureLANFirewall()
    {
        std::vector<std::wstring> firewallRules = {
            // 允许局域网内所有通信
            L"netsh advfirewall firewall add rule name="LAN Full Access" dir=in action=allow localip=192.168.10.0/24",
            L"netsh advfirewall firewall add rule name="LAN Full Access Out" dir=out action=allow remoteip=192.168.10.0/24",
            
            // 允许文件共享端口
            L"netsh advfirewall firewall add rule name="LAN SMB" protocol=TCP localport=139,445 action=allow dir=in",
            L"netsh advfirewall firewall add rule name="LAN SMB Out" protocol=TCP localport=139,445 action=allow dir=out",
            
            // 允许远程桌面
            L"netsh advfirewall firewall add rule name="LAN RDP" protocol=TCP localport=3389 action=allow dir=in",
            
            // 允许Ping
            L"netsh advfirewall firewall add rule name="LAN ICMP" protocol=icmpv4:8,any action=allow dir=in"
        };
 
        for (const auto& rule : firewallRules) {
            ExecuteCommand(rule);
        }
    }
 
    // 启用局域网服务
    void EnableNetworkServices()
    {
        std::vector<std::wstring> serviceCommands = {
            L"net start LanmanServer",    // 文件共享服务
            L"net start FDResPub",        // 功能发现服务
            L"net start SSDPSRV",         // SSDP发现服务
            L"net start upnphost",        // UPnP服务
            L"net start dnscache",        // DNS客户端服务
        };
 
        for (const auto& cmd : serviceCommands) {
            ExecuteCommand(cmd);
        }
    }
 
    // 设置DHCP服务器(可选)
    void SetupDHCPServer(const std::wstring& virtualAdapter)
    {
        std::wcout << L"配置DHCP服务器..." << std::endl;
 
        std::vector<std::wstring> dhcpCommands = {
            L"netsh interface ipv4 set address name="" + virtualAdapter + L"" static 192.168.10.1 255.255.255.0",
            L"netsh dhcp add server " + virtualAdapter + L" 192.168.10.1",
            L"netsh dhcp server 192.168.10.1 add scope 192.168.10.0 255.255.255.0 "LAN Scope" "Local Network"",
            L"netsh dhcp server 192.168.10.1 scope 192.168.10.0 add iprange 192.168.10.100 192.168.10.200",
            L"netsh dhcp server 192.168.10.1 scope 192.168.10.0 set optionvalue 003 IPADDRESS 192.168.10.1",
            L"netsh dhcp server 192.168.10.1 scope 192.168.10.0 set optionvalue 006 IPADDRESS 192.168.10.1"
        };
 
        for (const auto& cmd : dhcpCommands) {
            ExecuteCommand(cmd);
        }
    }
 
private:
    DWORD ExecuteCommand(const std::wstring& command)
    {
        STARTUPINFO si = { sizeof(si) };
        PROCESS_INFORMATION pi;
        std::wstring cmdLine = L"cmd.exe /c " + command;
 
        if (CreateProcess(NULL, &cmdLine[0], NULL, NULL, FALSE, 
                         CREATE_NO_WINDOW, NULL, NULL, &si, &pi)) {
            WaitForSingleObject(pi.hProcess, INFINITE);
            DWORD exitCode;
            GetExitCodeProcess(pi.hProcess, &exitCode);
            CloseHandle(pi.hProcess);
            CloseHandle(pi.hThread);
            return exitCode;
        }
        return GetLastError();
    }
};
 
// 性能测试函数
void PerformNetworkTest(const std::wstring& targetIP)
{
    std::wcout << L"
正在进行网络性能测试..." << std::endl;
 
    // 测试延迟
    std::wstring pingCmd = L"ping -n 10 " + targetIP;
    std::wstring pingResult = ExecuteCommandWithOutput(pingCmd);
    
    // 解析平均延迟
    size_t pos = pingResult.find(L"平均 = ");
    if (pos != std::wstring::npos) {
        std::wcout << L"平均延迟: " << pingResult.substr(pos, 50) << std::endl;
    }
 
    // 测试带宽(使用iperf等工具)
    std::wcout << L"建议使用iperf进行带宽测试: iperf3 -c " << targetIP << std::endl;
}

WiFi Direct 的工作机制

WiFi Direct创建的虚拟热点不需要传统的Internet共享就能让设备连接,因为它使用的是不同的网络架构:

传统热点 vs WiFi Direct热点

特性 传统承载网络热点 WiFi Direct热点
需要Internet共享 ✅ 必须设置 ❌ 不需要
网络拓扑 NAT转换 点对点直连
连接方式 客户端-服务器 点对点
IP分配 DHCP服务器分配 组所有者分配
共享配置 需要手动设置 自动配置

如果电脑没有wifi网卡,可以发布热点出来吗?

不同情况的分析

1. 电脑完全没有WiFi网卡 ❌

如果电脑完全没有任何无线网卡(包括USB无线网卡),那么:

无法创建WiFi Direct热点

WiFi Direct需要物理无线硬件支持

无法发射无线信号

2. 电脑有WiFi网卡但被禁用 ✅

如果电脑有WiFi网卡但被软件禁用:

可以创建WiFi Direct热点

WiFi Direct会自动启用无线网卡

手机可以连接热点

3. 电脑只有有线网卡 ❌

如果电脑只有以太网卡,没有无线网卡:

无法创建WiFi热点

需要额外购买USB无线网卡

自动创建WiFi Direct热点后,不设置虚拟wifi网卡属性中的共享internet 或 不设置真实wifi网卡属性中的共享internet 都可以发布wifi热点出来,手机都可以连上 但是这个速度很慢。如果选择共享internet方式,速度要快些。

您说得非常对!这正是WiFi Direct和传统Internet共享的关键区别:

速度差异的原因

1. WiFi Direct模式(慢)

cpp

// WiFi Direct使用点对点架构
void WiFiDirectMode()
{
    // 网络路径: 手机 → WiFi Direct虚拟适配器 → 应用程序处理
    // 需要经过额外的协议转换和处理层
    // 速度较慢,延迟较高
}

2. Internet共享模式(快)

cpp

// Internet共享使用内核级转发  
void InternetSharingMode()
{
    // 网络路径: 手机 → 虚拟适配器 → 内核NAT → 物理网卡
    // 内核直接处理数据包转发
    // 速度更快,延迟更低
}
© 版权声明

相关文章

暂无评论

none
暂无评论...