ZeroTierOne Android SDK 集成:6 步把跨网设备拉进同一个虚拟局域网
【免费下载链接】ZeroTierOneA Smart Ethernet Switch for Earth项目地址: https://gitcode.com/GitHub_Trending/ze/ZeroTierOne
你的笔记本在办公室内网,手机在咖啡店 Wi-Fi 上,两台设备分属 10.0.1.x 和 192.168.50.x 两个网段,屏幕共享 App 一直转圈。ZeroTierOne 的思路是"拉一根看不见的网线":把所有设备拽进同一个虚拟局域网,之后它们就像插在同一个交换机上,跨运营商、跨地域直接互通。而 SDK 集成,就是让你不用引导用户装客户端,直接在自己的 Android App 里内嵌这套虚拟网络能力。
SDK 长什么样:先认识两个角色
你打交道的主要是Node类,它是全部业务操作的入口;JNI 层则负责把 Java 方法翻译成 C++ 核心实现。分工大致是这样:
┌──────────────────────────────────┐ │ 你的 App(Java) │ │ com.zerotierone.sdk.Node │ ← init / join / 收发都在这里 ├──────────────────────────────────┤ │ JNI 胶水层 [java/jni/] │ ← 参数转换、对象缓存 ├──────────────────────────────────┤ │ C++ 核心(node/ + osdep/) │ ← 交换、加密、路由的真正实现 └──────────────────────────────────┘Node.java源码在 java/src/com/zerotier/sdk/Node.java,读不懂 C++ 也完全没关系,你只需要认识这张图。
环境版本要求与两个环境变量怎么配
动手前先对一下清单,缺什么补什么:
| 项目 | 版本要求 |
|---|---|
| JDK | 8 及以上 |
| Android NDK | r21 及以上 |
| Android SDK | API 21 及以上 |
| 构建工具 | ANT |
另外要设置两个环境变量,详见 java/README.md:
| 变量 | 指向 |
|---|---|
NDK_BUILD_LOC | NDK 里ndk-build脚本的完整路径 |
ANDROID_PLATFORM | android.jar所在目录 |
集成六步走
第 1 步:引入 so 库
目的:让 Java 能找到本地代码。做法:把编译产物libZeroTierOneJNI.so放进app/src/main/jniLibs/,并在加载处写一行:
static { System.loadLibrary("ZeroTierOneJNI"); }完成标志:App 启动加载类时不抛UnsatisfiedLinkError。
第 2 步:创建 Node 实例
目的:拿到操作入口。做法:用当前时间戳构造一个Node:
long now = System.currentTimeMillis(); Node node = new Node(now);完成标志:拿到可用的node对象,此时还未就绪。
第 3 步:init 初始化,7 个监听器各管一摊
目的:把存储、发包、回调全部接好。做法:实现 7 个接口传给init,每个监听器一句话:
| 监听器 | 一句话职责 |
|---|---|
| DataStoreGetListener | 从你的持久化存储里"读"节点数据 |
| DataStorePutListener | 把节点数据"写"回存储 |
| PacketSender | 把 ZeroTier 包真正发到物理网络上 |
| EventListener | 接收状态变化与非致命错误通知 |
| VirtualNetworkFrameListener | 收到虚拟局域网里其他设备发来的以太网帧 |
| VirtualNetworkConfigListener | 网络被创建、删除或配置变更时通知 |
| PathChecker | 可选,检查网络路径质量,可传 null |
调用长这样(pathChecker 可以为 null):
ResultCode r = node.init(getListener, putListener, sender, eventListener, frameListener, configListener, null);完成标志:r == ResultCode.OK。
第 4 步:join 加入网络
目的:让你的设备"上交换机"。做法:拿一个 64 位虚拟网络 ID 调join:
long nwid = 0x1234567890ABCDEF; // 虚拟网络 ID node.join(nwid);完成标志:随后VirtualNetworkConfigListener回调收到该网络的配置。
第 5 步:帧与包的收发
目的:让虚拟流量真正流动。做法:物理网络收到 UDP 包时喂给processWirePacket,要把帧发给虚拟局域网里的其他设备时调processVirtualNetworkFrame:
node.processWirePacket(now, localSocket, remoteAddr, packetData, nextDeadline); node.processVirtualNetworkFrame(now, nwid, srcMac, dstMac, etherType, 0, frameData, nextDeadline);完成标志:两端设备互相 ping 通。
第 6 步:定时跑后台任务
目的:让心跳、路径检测等周期工作运转。做法:按每次返回的nextDeadline定期调用:
node.processBackgroundTasks(now, nextDeadline);完成标志:nextDeadline持续有值更新,链路保持稳定。
避坑指南
- 现象:首次 init 卡了几秒。→原因:第一次要生成节点身份。→处理:UI 上给个加载态,别当成卡死。
- 现象:多个 Node 行为互相串台。→原因:监听器实例被共用。→处理:每个 Node 必须配自己的一套监听器实例。
- 现象:断网、错误悄无声息。→原因:状态与错误都走 EventListener,没人消费。→处理:认真处理每一种事件,别吞掉。
- 现象:App 退出后内存不释放。→原因:没调 close。→处理:退出前执行
node.close(),之后再不能复用该对象。
进阶速览
多播组按需订阅和退订:
node.multicastSubscribe(nwid, groupMac); node.multicastUnsubscribe(nwid, groupMac);Moon 是给特定地理区域"装加速器"的,加入与移除:
node.orbit(moonWorldId, moonSeed); node.deorbit(moonWorldId);想动手就先把源码拉下来,按上面六步走一遍:
git clone https://gitcode.com/GitHub_Trending/ze/ZeroTierOneAndroid 篇到这里,iOS 端的接入姿势我们下一篇见。
【免费下载链接】ZeroTierOneA Smart Ethernet Switch for Earth项目地址: https://gitcode.com/GitHub_Trending/ze/ZeroTierOne
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考