ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Wi-Fi Direct Services UWP 示例详解:在 Windows 10 上发布与发现 Wi-Fi Direct 服务

Wi-Fi Direct Services UWP 示例详解:在 Windows 10 上发布与发现 Wi-Fi Direct 服务 示例工程【免费下载链接】Windows-universal-samplesAPI samples for the Universal Windows Platform.项目地址https://gitcode.com/gh_mirrors/wi/Windows-universal-samples点击查看免费下载本文以 Windows-universal-samples 仓库中的 WiFiDirectServices 示例 为核心系统讲解如何在 UWP 应用中基于Windows.Devices.WiFiDirect.ServicesAPI 实现服务的发布Advertise、发现Discover、连接Connect与数据传输Send Data。读完本文你将掌握 Wi-Fi Direct Services API 的完整调用链、广告方Advertiser与发现方Seeker两种角色的实现要点以及如何在实际设备上构建、部署并验证这套点到点通信方案。什么是 Wi-Fi Direct Services基于 Enable 服务的自定义服务Wi-Fi Direct Services API 依据 Wi-Fi 联盟Wi-Fi Alliance规范提供Enable 服务它允许开发者定义自定义 服务service由一台设备对外广播advertise另一台设备发现discover并连接。与传统的 Wi-Fi Direct仅建立设备间连接不同Services 层在连接之上抽象出服务名与服务信息的概念使两台设备可以基于约定的服务名而不是 MAC 地址来互相发现和通信。从示例的 Package.appxmanifest 可以看到运行该示例需要两项关键声明Capabilities Capability NameinternetClientServer / DeviceCapability Nameproximity / /CapabilitiesinternetClientServer允许应用使用 TCP/UDP socket 进行网络通信Wi-Fi Direct 会话建立后通过 socket 传数据proximityWi-Fi Direct 等近距离无线通信所需的设备功能声明缺少它将无法调用 Services API。同时清单将目标设备族声明为Windows.Universal最小版本10.0.10240.0即面向 Windows 10 及更高版本。重要硬件前提本示例需要两台或更多搭载支持 Wi-Fi Direct services 的 Wi-Fi 芯片与驱动的设备。单台设备无法完成发布→发现→连接的闭环验证。示例功能全景五个可运行场景示例以SDKTemplate通用框架组织 UI在 SampleConfiguration.cs 中注册了 5 个场景Scenario完整覆盖了 Wi-Fi Direct Services 的两端角色场景名称角色核心能力Scenario1Create Advertiser广告方配置并启动服务发布Scenario2Advertiser Accept广告方接受/拒绝接入请求、管理已连接会话Scenario3Discover/Connect Services发现方按服务名发现服务并建立连接Scenario4Select Session (Seeker)发现方查看/关闭已建立的会话Scenario5Send Data双方通过 TCP/UDP socket 收发数据示例把全部业务逻辑收敛在两个核心文件中状态管理与 API 调用的 WiFiDirectServiceManager.cs以及各类 API 对象封装与事件处理的 WiFiDirectServiceWrappers.csC 版本对应 WiFiDirectServicesManager.cpp 与 WiFiDirectServicesWrappers.cpp。UI 层只负责收集用户输入并调用管理器这种分层正是 UWP 示例的标准做法。场景一发布一个服务Advertiser Create服务发布的核心类是WiFiDirectServiceAdvertiser。在 WiFiDirectServiceManager.cs 的StartAdvertisement方法中可以看到完整的配置项下面逐一说明其约束与含义。服务名ServiceName的命名约束WiFiDirectServiceAdvertiser advertiser new WiFiDirectServiceAdvertiser(serviceName);源码注释给出了三条硬性约束服务名内部限制为UTF-8 编码下最多 255 字节合法字符包括字母数字、.、-以及任意多字节字符发现服务时a-z / A-Z 不区分大小写。实际开发中建议使用类似反向域名如com.example.games.foobar的命名约定保证跨应用可发现。自动接受与会话建立模式advertiser.AutoAcceptSession autoAccept; advertiser.PreferGroupOwnerMode preferGO;AutoAcceptSession为true时服务在发现方发起连接后无需广告方人工干预即可建立会话。但注意若连接所需的配置方法要求 PIN则即使设置了自动接受广告方也必须接受连接PIN 需要人工核对。PreferGroupOwnerMode是否倾向成为 P2P 连接的组所有者Group Owner, GO。示例默认勾选源码注释解释了原因GO 可以同时连接多个客户端而作为客户端的设备只能连接一个 GO。因此把广告方设置为 GO可以支撑一对多的连接拓扑。服务状态与自定义状态码advertiser.ServiceStatus status; advertiser.CustomServiceStatusCode customStatus;WiFiDirectServiceStatus的默认值是Available可用。若业务需要表达忙碌或自定义状态可选择Busy或Custom此时通过CustomServiceStatusCode传入自定义状态码大于 1 的值。Scenario1_AdvertiserCreate.xaml.cs 展示了 UI 上如何把下拉选项映射为状态枚举并把文本框内容解析为uint自定义码。服务信息ServiceInfo与延迟会话信息DeferredSessionInfoadvertiser.ServiceInfo serviceInfoDataWriter.DetachBuffer(); advertiser.DeferredSessionInfo deferredSessionInfoDataWriter.DetachBuffer();这两个缓冲区的语义不同是示例注释中最值得注意的细节ServiceInfo最多 65000 字节随广播发布的服务信息。发现方可以显式地指定一个该缓冲区子集的短缓冲区来定向发现——若发现方提供的片段与广播内容匹配则整个缓冲区会返回给发现方若不匹配服务信息不会返回。示例用字符串承载但实际可以是任意数据。DeferredSessionInfo最多 144 字节当连接被延迟deferred即未自动接受时发给发现方的信息。它会在AutoAcceptSession false、或连接需要 PIN 时被发送。发现方通过WiFiDirectService.SessionDeferred事件收到该信息见 WiFiDirectServiceWrappers.cs 的OnSessionDeferred。两者都通过DataWriter写入InMemoryRandomAccessStream后DetachBuffer()得到IBuffer这是 WinRT 中构造缓冲区的标准写法。支持的配置方法Configuration Methodsadvertiser.PreferredConfigurationMethods.Add(configMethod);配置方法决定了会话建立时是否需要 PIN 以及 PIN 的输入方式取值来自WiFiDirectServiceConfigurationMethodDefaultWFD Services 默认不需要显式输入 PIN连接体验最无缝PinDisplay广告方显示 PIN发现方查看后输入PinEntry发现方显示 PIN广告方查看后输入。示例 UI 中 Scenario1 允许同时勾选多种方法。源码注释给出典型组合建议广告方通常支持 PinDisplay及 Default发现方用 PinEntry 或 Default 连接。服务名前缀Service Name Prefixesadvertiser.ServiceNamePrefixes.Add(prefix);广告方可以显式声明允许被前缀匹配发现的服务名前缀。示例 UI 支持动态添加/删除前缀列表源码注释强调两点每个前缀都会由驱动处理因此支持的数量有限应用只应发布发现所必需的前缀前缀必须是服务名的真实前缀否则发布会失败。例如服务名com.example.games.foobar合法前缀是com.example.games。启动与停止发布advertiser.Start(); // 必须从 UI 线程调用 advertiser.Stop(); // 停止广播Start()可能因驱动无法处理请求或设备不支持 Services 而抛出异常示例会捕获并向用户报告WiFiDirectServiceManager.cs。注意Start()必须从应用的 UI 线程调用。UnpublishService通过Stop()停止广播包装类AdvertisementWrapper在Dispose()中也会在状态为Started时调用Stop()并注销事件处理器WiFiDirectServiceWrappers.cs。广告方的三个关键事件由AdvertisementWrapper注册WiFiDirectServiceWrappers.cs事件触发时机处理AdvertisementStatusChanged服务创建/启动或广播因任何原因停止状态为Aborted/Stopped时从列表移除广告AutoAcceptSessionConnected自动接受的会话已连接包装会话并加入会话列表SessionRequested收到必须显式接受/拒绝的会话请求展示 PIN 提示等待用户操作场景二接受或拒绝接入请求Advertiser Accept当广告方未开启自动接受、或连接需要 PIN 时SessionRequested事件触发请求进入WiFiDirectServiceSessionRequest队列。AdvertisementWrapper会解析请求中的SessionInfo发现方随请求发送的信息并在ProvisioningInfo.IsGroupFormationNeeded SelectedConfigurationMethod PinDisplay时提示广告方远端应输入 PINxxxWiFiDirectServiceWrappers.cs。接受连接PIN 的三种判定分支AcceptSessionRequestWiFiDirectServiceWrappers.cs按ProvisioningInfo分三条路径处理 PINif (request.ProvisioningInfo.IsGroupFormationNeeded request.ProvisioningInfo.SelectedConfigurationMethod WiFiDirectServiceConfigurationMethod.PinDisplay) { pinForConnect this.pin; // 广告方展示的 PIN发现方输入 } else if (request.ProvisioningInfo.IsGroupFormationNeeded request.ProvisioningInfo.SelectedConfigurationMethod WiFiDirectServiceConfigurationMethod.PinEntry) { if (pin.Length 0) throw new ArgumentException(Expected PIN for connection, not provided); pinForConnect pin; // 发现方展示的 PIN广告方输入 } else { pinForConnect ; // 无需 PIN }随后调用advertiser.ConnectAsync(request.DeviceInformation[, pinForConnect])完成会话建立。该调用同样必须来自 UI 线程。拒绝连接拒绝的实现很简洁直接request.Dispose()即可WiFiDirectServiceWrappers.cs随后请求会从队列和 UI 中移除。场景三发现服务并建立连接Seeker Discover发现方一侧的核心是WiFiDirectService.GetSelector与DeviceInformation.FindAllAsync实现在 WiFiDirectServiceManager.cs 的DiscoverServicesAsync中。构造设备选择器if (requestedServiceInfo ) { serviceSelector WiFiDirectService.GetSelector(serviceName); // 仅按服务名搜索 } else { serviceSelector WiFiDirectService.GetSelector(serviceName, serviceInfoDataWriter.DetachBuffer()); // 按服务名服务信息片段搜索 }GetSelector有两个重载只传服务名时按名发现额外传入IBuffer时会在发现过程中尝试匹配广播方的ServiceInfo——匹配规则与广告方侧一致发现方提供的短缓冲区是广播方服务信息缓冲区的子集时完整信息才会返回。请求附加属性并执行发现DeviceInformationCollection deviceInfoCollection await DeviceInformation.FindAllAsync(serviceSelector, additionalProperties);示例通过FindAllAsync一次性完成发现并返回列表同时请求了 5 个 Wi-Fi Direct Services 相关的系统属性ServiceAddress、ServiceName、ServiceInformation、AdvertisementId、ServiceConfigMethods。DiscoveredDeviceWrapper.ParsePropertiesWiFiDirectServiceWrappers.cs把这些属性解析为强类型字段其中ServiceAddress是 MAC 地址字节数组会被格式化为XX:XX:XX:XX:XX:XX字符串。源码注释还提到一个进阶替代方案DeviceWatcher可以在服务一被发现就持续推送更新直到显式停止适合需要持续在线发现的应用FindAllAsync则适合一次性扫描。连接的两种方式Scenario3_SeekerDiscover.xaml.cs 的注释总结了发现方的两条连接路径两条路径都先经过WiFiDirectService.FromIdAsync(deviceInfo.Id)打开服务对象见OpenSessionAsyncWiFiDirectServiceWrappers.cs先获取预配置信息再连接调用GetProvisioningInfoAsync(configMethod)判断是否需要组建群组、是否需要 PIN需要 PINIsGroupFormationNeeded且配置方法为PinEntry/PinDisplay时ConnectAsync(pin)传入 PIN不需要 PIN 时直接ConnectAsync()。直接连接不查询预配置信息直接ConnectAsync()此时优先使用 WFD Services 默认配置方法Default。示例 UI 允许发现方预先设置两个选项SetServiceOptionsAsyncWiFiDirectServiceWrappers.csPreferGroupOwnerMode本端是否倾向成为组所有者SessionInfo随连接请求发送给广告方的可选 144 字节信息缓冲区与广告方的DeferredSessionInfo对应。GetProvisioningInfoAsync的返回值WiFiDirectServiceProvisioningInfo携带两个关键字段IsGroupFormationNeeded是否需要组建 P2P 群组与SelectedConfigurationMethod最终选定的配置方法发现方据此决定是显示 PIN还是输入 PINWiFiDirectServiceWrappers.cs。场景四与场景五会话管理与 TCP/UDP 数据传输会话对象与会话状态连接成功后得到WiFiDirectServiceSession示例用SessionWrapper封装WiFiDirectServiceWrappers.cs暴露会话的四个身份字段AdvertisementId广告实例 IDSessionId会话 IDServiceAddress服务地址MAC 格式SessionAddress会话地址。SessionWrapper注册了SessionStatusChanged状态变为Closed时自动从管理器清理会话和RemotePortAdded对端打开端口时触发两个事件并在Close()中先释放所有 socket 再Dispose()会话用AutoResetEvent等待关闭确认正常情况下 5 秒内完成。在会话上打开 TCP/UDP 端口SessionWrapper提供两个方法向会话注册本端端口AddStreamSocketListenerAsync(port)TCP创建StreamSocketListener通过session.GetConnectionEndpointPairs()[0].LocalHostName绑定到会话本地地址然后调用session.AddStreamSocketListenerAsync(listenerSocket)把监听器注册到会话上WiFiDirectServiceWrappers.csAddDatagramSocketAsync(port)UDP创建DatagramSocket绑定后调用session.AddDatagramSocketAsync(socket)注册。源码注释特别说明示例中该 socket 是只读的——应用先启动监听等远端发数据WiFiDirectServiceWrappers.cs。关键机制当对端调用AddStreamSocketListenerAsync/AddDatagramSocketAsync注册端口时本端会触发RemotePortAdded事件。OnRemotePortAddedWiFiDirectServiceWrappers.cs根据args.Protocol是Tcp还是Udp创建StreamSocket或DatagramSocket并通过ConnectAsync(endpointPairCollection[0])主动连向对端端口完成端口登记 主动连接的双向打通。消息协议长度前缀 字符串SocketWrapperWiFiDirectServiceWrappers.cs统一封装了 TCP 与 UDP 的消息收发传输格式为uint32 长度前缀 UTF-8 字符串。writer.WriteUInt32(writer.MeasureString(message)); writer.WriteString(message); await writer.StoreAsync();接收端HandleReceivedMessage先LoadAsync(sizeof(uint))读长度再按长度加载并解码字符串TCP 是流式协议读完一条后会递归继续读下一条UDP 则通过DatagramSocket.MessageReceived事件回调处理load false分支每次事件对应一条完整消息。这正是示例能持续互发文本的底层原因。双向的 TCP 连接接纳在广告方一侧StreamSocketListenerWrapper监听ConnectionReceived事件一旦发现方连入就把收到的StreamSocket交给SessionWrapper.AddStreamSocketInternal随即启动递归接收循环并加入 socket 列表WiFiDirectServiceWrappers.cs。至此两端各持有可读可写的 socket即可互发文本消息。系统要求依据 README.md 的系统要求部分ClientWindows 10ServerWindows Server 2016 Technical PreviewPhoneWindows 10硬件两台或更多搭载支持 Wi-Fi Direct services 的 Wi-Fi 芯片与驱动的设备除非用本示例与其他支持 Wi-Fi Direct services 的设备交互构建与运行示例提供 C#、Ccppcx两种实现各自包含完整的.sln解决方案cs/WiFiDirectServices.sln、cpp/WiFiDirectServices.sln以及对应的项目文件WiFiDirectServices.csproj、WiFiDirectServices.vcxproj。构建步骤若下载的是示例集合 ZIP务必解压整个压缩包而不是只解压本示例所在文件夹——示例依赖仓库根目录的SharedContent共享资源README 的 front matter 中extendedZipContent已声明该依赖。启动 Visual Studio选择文件 → 打开 → 项目/解决方案。定位到Samples/WiFiDirectServices下的cs或cpp子文件夹双击.sln文件。按CtrlShiftB或选择生成 → 生成解决方案。运行步骤仅部署选择生成 → 部署解决方案部署并调试运行按F5或选择调试 → 开始调试不调试直接运行按CtrlF5或选择调试 → 开始执行不调试。验证提示要真正完成发现并连接服务的闭环至少需要把示例部署到两台设备上单台设备只能观察发布/发现过程无法建立会话。两台设备可分别扮演广告方Scenario1→Scenario2与发现方Scenario3→Scenario4最后任选一端在 Scenario5 中打开 TCP 或 UDP 端口互发文本。关键实现文件索引以下文件是本示例的核心便于进一步阅读源码cs/WiFiDirectServiceManager.cs单例管理器封装发布、发现、会话列表与 UI 状态同步cs/WiFiDirectServiceWrappers.csAdvertisementWrapper、DiscoveredDeviceWrapper、SessionWrapper、SocketWrapper等 API 对象封装与事件处理cs/Scenario1_AdvertiserCreate.xaml.cs广告方配置 UI 与参数收集cs/Scenario3_SeekerDiscover.xaml.cs发现方 UI含两条连接路径cs/Package.appxmanifestproximity与internetClientServer能力声明cs/SampleConfiguration.cs五个场景的注册与导航cpp/WiFiDirectServicesManager.cpp 与 cpp/WiFiDirectServicesWrappers.cppCcppcx版本对应实现cs/Helpers/BufferConverter.cs 与 cs/Helpers/ServiceStatusConverter.cs缓冲区与状态枚举的转换辅助类。整体来看这个示例完整演示了 Wi-Fi Direct Services 从服务命名 → 广播发布 → 按名发现 → 预配置协商PIN→ 会话建立 → TCP/UDP 数据通道的整条链路。对于需要构建近距离、无路由器场景下点对点通信应用的开发者这套 API 与示例代码是很好的起点。赞分享示例工程【免费下载链接】Windows-universal-samplesAPI samples for the Universal Windows Platform.项目地址https://gitcode.com/gh_mirrors/wi/Windows-universal-samples点击查看免费下载相关推荐Wi-Fi Direct UWP 示例详解设备广播发现、配对连接与套接字数据传输Windows-universal-samplesWi Fi Direct UWP 示例详解设备广播发现、配对连接与套接字数据传输Windows universal samples 导读 本文围绕 Win示例工程探索Wi-Fi Direct叶子C的开源项目WifiP2P探索Wi Fi Direct叶子C的开源项目WifiP2P 在数字化时代无线通信技术不断演变其中Wi Fi Direct是一个极具潜力的技术它允许设备间Multitarget-tracker ByteTrack算法实现高精度多目标跟踪新选择Multitarget tracker ByteTrack算法实现高精度多目标跟踪新选择 Multitarget tracker是一款基于匈牙利算法和卡尔曼滤计算机视觉视频上一篇Notepad--跨平台文本编辑器的终极解决方案打造你的专属代码工作台下一篇Step-Audio语音合成可扩展性设计支持百万级用户的架构方案创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表