首页/新闻资讯/正文详情

异地组网客户端开发实录:P2P 打洞、在线判定、老系统兼容踩过的坑

发布时间:2026/9/27 6:11:56 来源:云帆数科 栏目:资讯中心
异地组网客户端开发实录:P2P 打洞、在线判定、老系统兼容踩过的坑
摘要把我手上的几台机器连成一张虚拟局域网Windows、Linux、Android 三端引擎用 EasyTier账号、调度、锚点、后台都自己搭。这里只记三件事为什么有台设备死活走不了 P2P在线状态为什么不能指望客户端心跳CentOS 7 上跑不起来怎么办。仓库在文末。先说这个东西是干什么的需求很土我自己名下几台机器家里台式机、公司电脑、一台 NAS加两部手机想把它们连成一张虚拟局域网。能互相 ping 通能联机开服能共享文件和打印机就够了。不好办的地方有三处开服那台没有公网 IP我也不想为它做端口映射虚拟 IP 必须固定机器换个网络不能变地址手机得能进现在做出来的形态是客户端登录填一个 8 位适配码客户端在本机拉起 EasyTier 引擎建虚拟网卡和路由。账号、设备分配、锚点调度在服务端。打洞和中继 EasyTier 自己都做了我写的其实是它外面那一圈。按踩坑的先后顺序讲。一、走不走 P2P先看 NAT 类型一开始我想的是两边都在国内、延迟又低直连应该没问题。结果有台设备一直挂在中继上速度只有几百 KB/s。查下来它是对称型 NAT。EasyTier 会把对端的 NAT 类型和当前链路一起报出来用自带的 CLI 就能看easytier-cli-p127.0.0.1:15888-ojson peer输出里每条对端长这样节选{ipv4:10.0.0.5,hostname:pc-a,cost:p2p,lat_ms:5.45,loss_rate:0.0%,tunnel_proto:tcp,udp,nat_type:SymmetricEasyInc}cost是p2p就是直连出现relay就是走中继了。nat_type常见的几种PortRestricted/Restricted锥形 NAT一般打得通Symmetric/SymmetricEasyInc端口每次都换打洞基本没戏知道这个以后我改了两处。客户端界面上把每个对端标出来是直连还是中继省得用户自己猜另外把能不能直连和节点延迟拆成两个指标。创建组网时我们会并发探测各调度节点的 TCP 延迟挑最近的那个当锚点但锚点近不代表这两台客户端之间打得到洞。这两个指标我曾经混在一起看结论是错的。中继现在在锚点侧限了速。它是兜底不是主路径。P2P 的数据不经过服务器不受这个限制。二、在线状态别指望客户端一开始的判定方式很直接客户端连上以后定时给服务端发心跳服务端写last_seen查询时看这个时间有没有超出窗口我们定的是 90 秒。Windows 和 Linux 都正常。安卓加进组网之后界面上一直是离线。查了半天是它压根没发心跳。安卓用系统VpnService建 tun再把 fd 交给 JNI 里的 EasyTier跟桌面端是两条完全不同的路写的时候漏了这一段。服务端记录里也看得出来那台机器的last_seen是 NULL。补心跳当然能解决但我想的是另一件事锚点本来就知道谁连着。所有客户端都得连锚点信令至少要从那儿过锚点上的对端列表比客户端自己报的准。让每个端各实现一遍心跳还得先定协议不如直接问锚点# 锚点的 RPC 端口按房间号算形如 16000 (房间号 % 2000)easytier-cli-p127.0.0.1:16021-ojson peer拿到对端 IP 列表跟数据库里该组网的成员按虚拟 IP 对一遍命中的就刷last_seen。这段逻辑放在锚点的管理脚本里跟着定时任务一分钟跑一次UPDATEnetwork_membersSETlast_seen?WHEREnetwork_id?ANDSUBSTRING_INDEX(v4_addr,/,1)IN(?,?,...)这样客户端不用配合。安卓那个没心跳的版本没更新Linux 的老版本也没更新都自动显示在线了。设备真断了之后对端会从锚点列表里消失last_seen不再刷新过窗口自然变离线。安卓那个坑我到现在也没回头去补心跳因为用不上了。三、固定虚拟 IP 交给服务端分需求是不删组网IP 就不变。实现不难重点是别让客户端自己决定。设备第一次加入某个组网时服务端在成员表里给它分配一个虚拟地址写进库顺便记下设备标识、网段和网关。之后这台机器的内网 IP 怎么变、重连多少次、客户端重装只要设备标识还在拿到的都是同一个地址。客户端那边就简单了登录、拉配置、从配置里读自己的虚拟地址、拿这个地址起引擎。不猜也不看本地网段。顺带说个容易搞错的点。虚拟机里跑游戏服务端监听地址填0.0.0.0有时候收不到组网网卡上过来的连接得显式写组网虚拟 IP。这个问题我查了很久最后确认是虚拟机的网络栈把0.0.0.0的绑定限制在某张网卡上了。不是组网的问题但确实踩过。四、老系统上跑不起来这块最费时间有台 CentOS 7 的机器要当组网节点。客户端装完命令行直接报错aipai: /lib64/libm.so.6: version GLIBC_2.27 not found (required by aipai) aipai: /lib64/libstdc.so.6: version GLIBCXX_3.4.22 not foundCentOS 7 是 glibc 2.17、GLIBCXX 3.4.19而客户端是 .NET 自包含程序底线是 glibc 2.27 加 GLIBCXX 3.4.22。这不是装个依赖就能补的事glibc 没法单独升级硬换会把系统弄坏。剩下的路只有容器。容器里的用户空间是新的虚拟网卡还是建在宿主机上效果跟直装一样docker run -d --name aipai --restart unless-stopped \ --network host --cap-add NET_ADMIN --cap-add NET_RAW \ --device /dev/net/tun \ -e AIPAI_USER账号 -e AIPAI_PASSWORD密码 -e AIPAI_NETWORK适配码 \ -v /opt/aipai-docker/app:/app -v /opt/aipai-docker/data:/root/.config/aipai \ -w /app 基础镜像 /app/aipai connect真做起来又踩了三个坑。第一个是镜像拉不动。国内访问 Docker Hub 基本没戏配了加速器也可能一起挂。最后的办法是把一个精简过的 Ubuntu 镜像放到自己服务器上官方镜像拉不到就docker import导进去dockerimportaipai-base.tar.xz aipai-base:jammy原镜像解包 684MB删掉包索引、Python、vim、文档和本地化之后剩 211MB压成 xz 是 50MB。容器里跑 .NET 需要的东西一个都不能少glibc、libstdc、libssl.so.3HTTPS 要用、根证书。这几个我是挨个 ls 确认过的。第二个坑更隐蔽。我给容器加了--restart unless-stopped它崩了会自动拉起。启动脚本检查状态那一瞬间容器恰好是 Running于是脚本报了已启动可日志里正在刷Failed to create CoreCLR。容器健康不能只看一眼状态。后来改成看三样日志里有没有致命错误、RestartCount是不是 0、日志里能不能看到已接入这类成功标记。dockerinspect-f{{.State.Running}} {{.RestartCount}}aipai第三个是老版 Docker 拦住了 .NET。CentOS 7 的源里是 Docker 1.132017 年的版本它默认的 seccomp 策略会拦掉 .NET 运行时需要的系统调用报出来的还是Failed to create CoreCLR, HRESULT: 0x80070008。这个错误码字面意思是内存不足实际是 syscall 被拦了。老内核上 .NET 的 W^X 也起不来一起关掉dockerrun... --security-optseccompunconfined\-eDOTNET_EnableWriteXorExecute0-eDOTNET_gcServer0\-eDOTNET_GCHeapHardLimitHex0x14000000...还有一点CentOS 7 的官方源 2024 年就下线了yum install会卡在失效的镜像上很久得先切到 vault 归档源。这个我在安装脚本里自动处理了不处理的话用户看到的就是命令敲下去没反应。五、几个现在回看还算合理的取舍组网内所有端口互通这是产品要的效果开服不用做端口映射。代价是用户协议里必须写清楚不能拿来对外暴露 80/443不能建站不能转租通道。技术上能做到跟使用边界是两件事能写在协议里就别等出事再补。中继一直留着但我没把它当卖点讲。对称型 NAT 打不通的时候总得有条退路不然用户直接判定软件是坏的。它限速、不承诺可用性因为它就是兜底不是线路。收费方式也从卖注册邀请码改成了按月收技术服务费。邀请码那套用户理解不了自己到底买了什么。现在写的是账号与设备管理、打洞调度、控制台、售后口径清楚也避开了卖流量这种怎么解释都别扭的说法。最后三端源码都在 GitHub 上https://github.com/wenzaiclub/aipai-link-clientWindows 是 WPFLinux 是命令行加一个网页面板Android 用 VpnService 加 JNI。服务端账号、调度、锚点、计费、后台没开源。要自己编译的话 README 里写了怎么拉 EasyTier 引擎Android 的原生库也提交在仓库里不用再交叉编译。哪块想细看比如锚点怎么按房间拉起独立进程或者客户端怎么按延迟选节点评论里说一声我另外写。

相关推荐

ThinkPHP6+Swoole+uni-app仿QQ即时通讯实战:架构、避坑与优化
ThinkPHP6+Swoole+uni-app仿QQ即时通讯实战:架构、避坑与优化

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/27 6:11:56

HFSS微带天线设计仿真全流程:从公式计算到报告输出
HFSS微带天线设计仿真全流程:从公式计算到报告输出

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/27 6:11:56

企业seo优化方案报价多少钱
企业seo优化方案报价多少钱

3个坑害企业官网SEO的致命漏洞避坑指南 网站做好了没人访问,是不是心在滴血?别急着加广告,先查查你的站是不是中了“隐形毒”。很多老板以为SEO就是堆关键词,其实 网站安全才是SEO的命门… · 2026/9/27 6:11:38

基础算法学习笔记
基础算法学习笔记

保持算法手感,但不必过度投入:确保能熟练解决 LeetCode Hot 100 中的动态规划、二叉树、链表类中等难度题目即可,足以应对国内大厂的“手撕”环节。 核心精力投入“手写组件”:这是你的差异化优势所在。你能理解推荐系统中的序列建… · 2026/9/27 6:45:56

conda中虚拟环境的使用
conda中虚拟环境的使用

查看所有虚拟环境 conda info --envs conda env list 新建一个虚拟环境(以tensorflow为例子) conda create -n tensorflow python3.5 conda create --prefixD:\anaconda20240917\envs\my37 python3.7 设置下载通道(使用清华镜像) con… · 2026/9/27 6:45:56

VEH HOOK
VEH HOOK

相关函数我们只需要用到 AddVectoredExceptionHandler 设置VEH异常捕获PVOID WINAPI AddVectoredExceptionHandler(_In_ ULONG FirstHandler,_In_ PVECTORED_EXCEPTION_HANDLER VectoredHandler );ULONG WINAPI RemoveVectoredExceptionHandler(_In_ PVO… · 2026/9/27 6:45:56

realme GT Neo6 全量包刷机教程:从原理到救砖实操指南
realme GT Neo6 全量包刷机教程:从原理到救砖实操指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/27 6:45:50

海康DS-K1F600U-D6E驱动部署全流程:从驱动安装到浏览器插件配置
海康DS-K1F600U-D6E驱动部署全流程:从驱动安装到浏览器插件配置

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/27 6:45:44

Agent 的账被小米算明白了:HySparse2 把百万上下文成本砍到 1/5
Agent 的账被小米算明白了:HySparse2 把百万上下文成本砍到 1/5

做 Agent 应用的人最近应该都有同一个感受:模型不贵,上下文贵。 一个 Agent 跑复杂任务,每调一次工具,可能就带回来一整页网页、一份文件、一长串执行日志。这些新内容要重新做预填充,历史记录还越攒越长。跑一个像样的… · 2026/9/27 6:45:32

MATLAB雷达信号脉冲压缩仿真:LFM线性调频、匹配滤波与距离分辨率实现
MATLAB雷达信号脉冲压缩仿真:LFM线性调频、匹配滤波与距离分辨率实现

简介:这套Matlab仿真工具完整呈现雷达信号脉冲压缩过程,从线性调频(LFM)信号生成、目标回波仿真到匹配滤波压缩处理均有可运行代码支撑,面向电子信息工程、计算机、数学等专业学生,适用于课程设计、期末大作… · 2026/9/27 0:00:01

汕头网站建设制作厂家避坑指南:5大注意事项救急
汕头网站建设制作厂家避坑指南:5大注意事项救急

汕头网站建设制作厂家避坑指南:5大注意事项救急 改个需求建站公司拖一周,这种憋屈事我见得太多了。 很多汕头老板找本地建站团队,签合同前看着方案挺美,一上线就变脸。 今天不聊虚的,直接拆解找 汕头网站建设制作厂家 时的5个核心 注意事项… · 2026/9/27 0:00:01

多模态虚假新闻检测实战:BERT+ResNet双塔与对比学习
多模态虚假新闻检测实战:BERT+ResNet双塔与对比学习

简介:基于PyTorch的多模态虚假新闻检测项目完整代码包,面向自然语言处理与计算机视觉交叉方向的开发者、科研人员及毕业设计选题者,解决社交媒体中文本与图像联合识别虚假新闻的问题。系统以BERT预训练模型提取文本语义特征,以Res… · 2026/9/27 0:00:01

MATLAB雷达信号脉冲压缩仿真:LFM线性调频、匹配滤波与距离分辨率实现
MATLAB雷达信号脉冲压缩仿真:LFM线性调频、匹配滤波与距离分辨率实现

简介:这套Matlab仿真工具完整呈现雷达信号脉冲压缩过程,从线性调频(LFM)信号生成、目标回波仿真到匹配滤波压缩处理均有可运行代码支撑,面向电子信息工程、计算机、数学等专业学生,适用于课程设计、期末大作… · 2026/9/27 0:00:01

汕头网站建设制作厂家避坑指南:5大注意事项救急
汕头网站建设制作厂家避坑指南:5大注意事项救急

汕头网站建设制作厂家避坑指南:5大注意事项救急 改个需求建站公司拖一周,这种憋屈事我见得太多了。 很多汕头老板找本地建站团队,签合同前看着方案挺美,一上线就变脸。 今天不聊虚的,直接拆解找 汕头网站建设制作厂家 时的5个核心 注意事项… · 2026/9/27 0:00:01

多模态虚假新闻检测实战:BERT+ResNet双塔与对比学习
多模态虚假新闻检测实战:BERT+ResNet双塔与对比学习

简介:基于PyTorch的多模态虚假新闻检测项目完整代码包,面向自然语言处理与计算机视觉交叉方向的开发者、科研人员及毕业设计选题者,解决社交媒体中文本与图像联合识别虚假新闻的问题。系统以BERT预训练模型提取文本语义特征,以Res… · 2026/9/27 0:00:01

了解更多?预约专属演示

我们的顾问将为您一对一讲解产品与方案

企业微信二维码