Tftpd64 鸿蒙 PC 适配全记录:用 Qt 重建一组可运行的 UDP 网络服务
欢迎加入开源鸿蒙 PC 社区:https://harmonypc.csdn.net/
欢迎在 PC 社区平台申请新建项目:https://atomgit.com/OpenHarmonyPCDeveloper
适配开源地址:https://atomgit.com/OpenHarmonyPCDeveloper/ohos_tftpd64
环境搭建文章:https://blog.csdn.net/weixin_52908342/article/details/161343743
一、为什么要适配 Tftpd64
Tftpd64 是一款面向局域网部署和设备维护的轻量网络工具。它把 TFTP、DHCP、DNS、SNTP 与 Syslog 集中在同一个桌面程序中,在交换机配置备份、开发板刷写、设备时间同步、启动参数分配和日志收集等场景里,往往比部署一整套服务器软件更直接。尤其在实验室和封闭网络中,工程师需要的通常不是复杂的集中管理平台,而是一个可以快速启动、能够看见请求过程、便于临时调整参数的工具箱。
选择 Tftpd64 进行 HarmonyOS PC 适配,价值不只在于迁移一个 Windows 窗口。它同时覆盖 UDP 监听、短连接协议、文件读写、局域网广播、低端口权限、后台运行和多服务状态管理,能够较完整地检验传统网络工具进入鸿蒙应用模型后会遇到的真实问题。如果这些边界处理得当,同类的设备发现、日志采集、轻量代理和调试服务也能沿用相近的技术路线。
本次适配以上游 Tftpd64 4.74 为基础,鸿蒙版本号为 4.74-ohos.1,应用 BundleName 为 com.pjo2.tftpd64.ohos,面向 2in1 与 tablet,Native 架构为 arm64-v8a。仓库保留原有 Win32 源码,鸿蒙工程独立放在 harmony_pc/ 下,避免平台重构影响上游代码结构。
二、先确定迁移边界:不是为 Win32 API 再造一层兼容壳
原版 Tftpd64 的界面来自 Win32 Dialog 与资源脚本,服务层又长期依赖 WinSock、Windows Service、Registry、Event、HANDLE 和 CRITICAL_SECTION。若以“让旧工程直接编译”为目标,就需要补齐大量仅对 Windows 有意义的类型和生命周期;即使最终通过编译,文件权限、网络端口和后台行为仍然不符合 HarmonyOS PC 的应用模型。
鸿蒙版本因此保留协议和用户工作流,替换平台外壳。Stage 模型负责应用入口与窗口生命周期,XComponent 承载 Qt for OpenHarmony 画面,Qt Widgets 重建桌面界面,QtNetwork 与 Native C++ 实现各项 UDP 服务。Windows Registry 改为 QSettings,任意路径访问改为系统文件选择器授权,Windows Service 则以应用生命周期和窗口隐藏恢复机制重新组织。
| 关注点 | 原版实现 | 鸿蒙侧处理方式 |
|---|---|---|
| 应用入口 | Win32 进程、窗口消息 | Stage 模型 EntryAbility |
| 桌面界面 | Dialog、资源脚本、原生控件 | XComponent + Qt 5 Widgets |
| 网络能力 | WinSock | QtNetwork / UDP Socket |
| 配置存储 | Registry、INI | QSettings 与应用沙箱 |
| 文件目录 | 任意本地路径 | 私有目录 + 系统文件选择器持久授权 |
| 后台行为 | Windows Service、托盘 | 关闭窗口隐藏、再次启动恢复 |
这条路线没有追求 Windows 二进制级兼容,而是把用户真正依赖的“启动服务—处理请求—查看结果—调整配置”闭环落到鸿蒙原生应用中。
三、鸿蒙版本的整体架构
鸿蒙工程由 ArkTS 宿主、Qt for OpenHarmony 运行层和 Native 服务层组成。ArkTS 侧保持轻量,只负责 Ability、窗口、XComponent 以及系统文件选择器;Qt 侧管理界面与服务状态,协议收发和解析逻辑都在同一个 Native 进程内完成。
EntryAbility
└── Index.ets / XComponent
└── Qt for OpenHarmony QPA
└── libentry.so
├── Qt Widgets 桌面界面
├── TFTP Server / Client
├── DHCP Server
├── DNS Server
├── SNTP Server
├── Syslog Server
└── QSettings / 日志 / 内置诊断
仓库中的主要目录如下:
ohos_tftpd64/
├── src/ # 上游 Windows 源码
├── tests/ # TFTP 协议与健壮性测试
├── README.OpenHarmony_CN.md # 鸿蒙适配说明
└── harmony_pc/
├── AppScope/app.json5 # 应用名称、包名和版本
├── build-profile.json5 # SDK、产品与签名配置
├── qtforharmony_sdk/ # Qt for OpenHarmony 运行库
└── entry/src/main/
├── ets/ # Ability、XComponent、文件选择器桥接
├── module.json5 # 模块、设备类型与权限声明
└── cpp/
├── CMakeLists.txt # Native 与 Qt 构建入口
├── ohos_napi_bridge.cpp # ArkTS/Qt 路径选择桥接
└── tftpd64_ohos_qt.cpp # 界面、协议服务与诊断逻辑
界面使用页签分别呈现 TFTP、DHCP、Syslog、SNTP、DNS 和总日志,但底层服务不是切换到页签后才启动。应用完成初始化后会集中建立监听,页签只是观察和控制相应服务的窗口,因此切换界面不会中断正在进行的网络请求。
四、在真机上跑通五个核心场景
以下五张截图均来自签名 HAP 在 HarmonyOS PC 2in1 真机上的实际运行画面,截图分辨率为 3120×2080。验证时通过 hdc 覆盖安装并启动 com.pjo2.tftpd64.ohos,应用在设备端实际建立 UDP 监听。启动后的内置诊断依次执行 TFTP、DNS、SNTP 和 DHCP 回环请求;Syslog 场景则由同一局域网中的 macOS 主机向真机发送 UDP 报文。
1. TFTP 服务完成启动与真实 RRQ 传输
主界面保留 Tftpd64 用户熟悉的工作方式:顶部统一选择根目录和监听接口,中间通过页签查看不同服务,底部持续汇总各项服务的运行端口。首次启动会在应用私有目录创建 tftp-root 和示例文件,避免因为公共目录没有授权而让服务停在不可写状态。

截图中的 tftpd64-sample.txt 并非静态占位记录。设备端诊断客户端向 TFTP 服务发出 RRQ,并携带 blksize=1024 与 tsize 选项;服务返回 OACK 后再发送 38 字节文件,传输表分别记录请求来源、文件名、开始时间和发送结果。这条路径覆盖了请求解析、选项协商、临时传输端口、数据块和最终 ACK。
2. DHCP 完成 Discover、Offer、Request 与 Ack
DHCP 页签展示当前租约。真机诊断使用测试客户端标识发出 Discover,服务从地址池中选择 192.168.109.200 并返回 Offer;随后收到 Request,再生成 Ack 和两小时租期。租约表中的 IP、MAC、到期时间与主机名来自实际协议处理结果。

这里需要特别区分“协议链路通过”和“可直接接管现网 DHCP”。前者已经由真机回环验证,后者必须在隔离网络中使用真实客户端测试,否则会与局域网已有 DHCP 服务竞争。项目没有把尚未完成的广播环境联调写成已经交付的能力。
3. Syslog 接收来自局域网另一台主机的报文
为了验证监听不是只在应用内部自说自话,macOS 主机 192.168.1.101 向真机 192.168.1.102:5514 发送了一条 UDP Syslog 消息。真机界面随即显示来源地址、源端口、接收时间和完整消息内容。

这一步证明数据确实穿过了两台设备之间的局域网链路。Syslog 页签和总日志使用同一份接收结果,便于一边查看结构化记录,一边通过 hilog 继续排查网络和生命周期问题。
4. DNS 服务解析 A 记录查询
DNS 服务当前聚焦最常用的 A 记录与通配应答。截图中的 tftpd64.local 查询由真机诊断客户端发出,服务解析查询名并返回配置地址 192.168.109.6,表格同时保留请求来源和应答内容。

与调用系统解析器不同,这里是应用自身在 UDP 8053 上接收和构造 DNS 报文。当前版本尚未扩展 AAAA、CNAME、MX 和 TXT 等记录类型,因此更准确的定位是面向调试与小型局域网的轻量 A 记录服务。
5. 总日志把端口降级与四项协议诊断串成一条证据链
Log viewer 记录了应用从启动到处理请求的完整顺序:标准低端口绑定被系统拒绝,服务切换到高位端口;随后 TFTP 完成 OACK 协商与文件发送,DNS 返回一条应答,SNTP 返回 v4、mode 4、stratum 1 时间包,DHCP 完成 Offer 与 Ack;最后还能看到外部主机发送的 Syslog 消息。

总日志比单纯显示“Running”更有价值。服务是否真正监听、协议是否产生应答、请求来自哪里、回退端口是多少,都可以在同一条时间线上核对;相同日志还会写入 hilog,出现设备侧问题时不必依赖界面截图才能定位。
五、适配过程中遇到的几个难点
难点一:低端口限制不是换一个 Socket API 就能解决
TFTP 69、DNS 53、DHCP 67、SNTP 123 和 Syslog 514 都属于低端口。普通 HarmonyOS HAP 在真机上绑定这些端口时会返回 The address is protected,这是系统权限边界,不是 QtNetwork 的实现缺陷。当前版本先尝试标准端口,失败后自动切换到 6969、8053、6767、8123 和 5514,并在页签状态、底部汇总栏和日志中明确标出 (fallback)。
这种处理保证了客户端端口可配置时工具能够直接使用,也保留了问题的可见性。对于只认标准端口的 PXE、交换机恢复模式等场景,仍需更高 APL 签名或由受控网络设备做端口转发,不能通过普通应用代码绕过。
难点二:TFTP 简单,但并不等于只收发一个 UDP 包
TFTP 的 RRQ/WRQ 从监听端口开始,真正的数据传输会切换到临时 TID;多块文件需要按序编号和逐块 ACK,最后一块还要处理 ACK 丢失后的驻留重发。加入 blksize、tsize 与 timeout 后,首包又可能从 DATA 变成 OACK。适配版为每次传输维护独立会话和计时器,同时限制路径只能落在根目录之内,防止 ../ 一类请求穿越应用允许的目录边界。
难点三:文件访问必须同时照顾沙箱与真实工作目录
把默认目录放进应用私有空间可以保证首次启动可写,但网络工具最终仍要与用户的下载、文档或固件目录交换文件。项目通过 NAPI 桥接 HarmonyOS DocumentViewPicker,用户选择目录后持久化授权,下次启动再激活权限。Qt 层只接收已经授权的路径,不假设任意绝对路径都能直接访问。
难点四:多项 UDP 服务需要共享生命周期,但不能相互拖累
五个服务的监听状态、日志和配置要在一个窗口中保持一致。若把服务创建绑定在页签切换事件上,后台页签会丢失请求;若关闭窗口就销毁进程,TFTP 或日志收集又会被意外中断。当前版本在主窗口初始化时统一启动服务,关闭窗口只隐藏界面并保留后台监听,再次点击应用图标恢复已有窗口。每项服务仍保有独立的 Socket、状态和停止入口,单项失败不会阻塞其他页签。
难点五:DHCP 真机验证必须尊重网络安全边界
DHCP 使用广播并影响客户端网络配置,不能为了截图直接在办公网络里替代现有 DHCP。项目先用设备内回环请求验证 Discover、Offer、Request 和 Ack 报文路径、租约时间以及地址池分配,再把真实客户端联调留给隔离网络。这不是减少测试,而是避免把协议验证变成网络事故。
难点六:Qt 运行库和 QPA 插件必须按目标架构完整入包
界面能够在开发机编译,不代表 HAP 在真机上一定能启动。libentry.so、Qt Core/Gui/Widgets/Network 运行库以及 libplugins_platforms_qopenharmony.so 都必须以 arm64-v8a 版本进入 HAP,ArkTS 的 XComponent 也要与 QPA 启动顺序对应。遗漏插件时通常只会看到空白窗口,混入开发机架构的动态库则会在装载阶段失败,因此产物检查必须放在安装前完成。
六、构建、安装与启动
工程的 compatible SDK 与 target SDK 均为 5.0.5(17)。首次构建建议使用 DevEco Studio 打开 harmony_pc/,确认 entry/build-profile.json5 中的项目内 Qt SDK 路径有效,并为 com.pjo2.tftpd64.ohos 配置与目标设备匹配的调试签名。
命令行构建示例如下:
cd harmony_pc
export DEVECO_SDK_HOME=/Applications/DevEco-Studio.app/Contents/sdk
export JAVA_HOME=/Applications/DevEco-Studio.app/Contents/jbr/Contents/Home
export PATH="/Applications/DevEco-Studio.app/Contents/tools/node/bin:$JAVA_HOME/bin:$PATH"
/Applications/DevEco-Studio.app/Contents/tools/hvigor/bin/hvigorw \
--mode module -p module=entry@default -p product=default \
assembleHap --no-daemon
签名产物位于:
harmony_pc/entry/build/default/outputs/default/entry-default-signed.hap
连接 HarmonyOS PC 后安装并启动:
hdc list targets
hdc install -r \
harmony_pc/entry/build/default/outputs/default/entry-default-signed.hap
hdc shell aa start \
-a EntryAbility -b com.pjo2.tftpd64.ohos -m entry
本文真机取证使用仓库生成的签名 HAP,包元数据中的版本为 4.74-ohos.1,目标 API 为 17,设备类型为 2in1 与 tablet。覆盖安装返回 install bundle successfully,Ability 启动返回 start ability successfully;随后完成五项服务监听、四项设备内协议诊断和一次跨设备 Syslog 收包,五张图片均由 snapshot_display 从当前真机画面取得。
七、当前功能边界
当前版本已经覆盖 Tftpd64 的主要使用路径:
- TFTP Server 的 RRQ/WRQ、octet 模式、
blksize、tsize、timeout与 OACK 协商; - TFTP Client 的基础 GET、PUT 和中断操作;
- DHCP 的 Discover/Offer、Request/Ack、Release/Inform、地址池和租约表;
- DNS A 记录与通配应答;
- SNTP 48 字节时间响应;
- Syslog UDP 监听、来源展示、复制与清理;
- 系统文件选择器、持久授权、应用私有默认根目录;
- 多服务统一日志、hilog 输出、窗口隐藏与恢复、配置持久化;
- 标准端口优先、受限时自动回退到可用高位端口。
尚未完成的部分也需要明确:TFTP windowsize 和 netascii 尚未实现;DHCP 静态租约与完整 PXE 启动链路仍待扩展;DNS 暂不提供 AAAA、CNAME、MX、TXT 等记录;标准低端口需要更高权限;Windows Service 和 Registry 不做原样迁移;DHCP 真实客户端广播联调需要隔离网络环境。
因此,当前版本更准确的定位是“Tftpd64 HarmonyOS PC 轻量网络服务版”。它已经可以在客户端端口可配置的实验室和设备调试场景中完成文件传输、地址分配协议验证、A 记录应答、时间响应和日志接收,但不应被描述为所有 PXE、低端口和企业 DHCP 场景的无条件替代品。
八、总结
Tftpd64 的适配说明,传统网络工具迁移到 HarmonyOS PC 时,真正需要重建的是平台边界,而不是窗口外观。WinSock 可以由 QtNetwork 承接,Registry 可以由 QSettings 替代,目录访问可以交给系统选择器,但低端口权限、应用沙箱、后台生命周期和局域网广播都必须按鸿蒙规则重新设计。
这次实践形成了一条清晰的落地顺序:先把多服务界面和运行状态放入 Stage + XComponent + Qt 的稳定宿主,再逐项恢复协议闭环;随后用自动端口回退处理普通应用权限,用目录授权解决真实文件交换,最后通过设备内协议诊断与跨设备 UDP 报文共同验证结果。对于此类工具,窗口能够打开只是起点,设备确实监听、请求确实到达、应答确实返回并且边界能够解释清楚,才算完成了有工程价值的适配。
更多推荐


所有评论(0)