xmz7891 b62ac865ea ykxmz 1.5.0:修复手表端 TLS 证书校验 + MTU 修复网络稳定性
被控端
- 修复 MTU 问题:夹 MSS + 路径 MTU 探测(公网可用率 48% -> 100%)
- 复用 HTTP 连接(免掉每次新建 TLS 的 30% 握手失败)
- 每分钟回头找局域网,自动切回快 400 倍的路径
- 画面心跳帧:静止时省流量,客户端仍知道流是活的
- 锁屏时给出可操作的提示

手表端
- 内置 GTS Root R4 / GlobalSign Root CA,修 SSLHandshakeException
- 连接错误翻译成人话(证书/时间/解析/超时分别提示)
- 经中转连上后用服务器报的地址刷新已配对记录
- 新增局域网连接页面、服务器延迟检测

服务器端
- 支持 chunked 请求体(修每 16 秒一次的连接错乱与大面积 502)
- 网络调优脚本 net-tune.sh(开机自动应用)
- 管理页:批量删除、网络体检、下载区
- 隧道改 HTTP/2 + 双连接

文档
- 许可协议 / 安装前必读 / 安装后须知(作者:小麦子)
2026-10-06 19:01:05 +08:00

局域网遥控 · LAN Remote

用手表(安卓)遥控自己的电脑。同一个 WiFi 下即可,不经过任何服务器。

┌─────────────────┐        局域网 TCP          ┌──────────────────┐
│  手表控制端 APK  │ ─────────────────────────► │  Windows 被控端   │
│  490×602 大按钮  │ ◄───────────────────────── │  可见托盘 + 配对码 │
└─────────────────┘                            └──────────────────┘

一、先说清楚这个工具「不是什么」

你最初的描述里,有几条我明确没有做,因为它们属于恶意软件特征:

你提的要求 为什么不做
注册成系统更新组件、杀毒软件杀不掉 这是免杀对抗。正常远控工具(TeamViewer、向日葵、AnyDesk)从不做这个。
托盘不显示、任务管理器里看不到 这是对电脑使用者隐藏自身。
伪装成普通系统文件常驻 持久化 + 伪装。

原因很简单:如果被控的是你自己的电脑,你不需要隐藏——你会希望它可见、能管理、能一键断开。而"杀软杀不掉、任务管理器看不到"只在一种场景下有意义:用电脑的人不知道你在控制它。

所以这一版是:被控端全程可见、可随时断开、权限可随时关闭。它是个正经工具,不是木马。


二、快速开始(3 步)

第 1 步:电脑端

把 LanRemote-Agent-Windows.zip 解压到任意目录,双击 LanRemote-Agent.exe。

程序会弹出窗口,窗口中间有一组 6 位配对码,例如:

        在手表上输入这组配对码
              4 5 4 5 3 4

窗口里同时能看到:

  • 当前连接状态
  • 防火墙是否放行(没放行会显示橙色提示 + 「一键修复」按钮)
  • 「打开接收目录」「退出」

关掉窗口 = 程序继续在后台跑(没有托盘图标)。 想再打开窗口,再双击一次 EXE 就行,不会重复起进程。 想彻底退出,在窗口上点「退出」。

第 2 步:手表端

安装 LanRemote-Watch-1.3.0.apk,打开后点那个大按钮 「自动搜索电脑」。

App 会往局域网广播一个探测包,被控端收到后回自己的名字和端口, 所以手表端不用输 IP、不用管网段、也不用管电脑上装了几个虚拟网卡。

搜到之后点一下那台电脑,输入被控端窗口上的 6 位数字,就连上了。

第 3 步:之后就不用再输了

配对成功后令牌保存在手表上,下次打开 App 会自动搜到并直接连, 连数字都不用再输。

多台电脑就配对多次,列表里点哪个连哪个。长按可以删除配对。

如果搜不到,展开「手动输入地址」可以自己填 IP 和端口 —— 但绝大多数情况 下搜不到都不是 IP 的问题,而是防火墙没放行(见下面第五节)。


工具箱(唯一入口)

被控端目录里有个 工具箱.bat,双击它就能看到所有功能:

============================================================
   局域网遥控 . 工具箱                      版本 1.3.0
============================================================

   1. 启动被控端          日常使用就点这个
   2. 一键修复防火墙      连不上时先试这个(需要管理员)
   3. 网络自检            还连不上就用它排查
   4. 查看使用说明
   5. 查看运行日志
   6. 打开接收文件夹
   7. 查看当前防火墙状态

   0. 退出

排查连接问题的推荐顺序:1 → 2 → 3。

选项 作用
1 启动被控端 确认程序在跑(任务管理器里能看到 LanRemote-Agent.exe)
2 一键修复防火墙 弹一次 UAC 点「是」。删掉「阻止」规则 + 补一条程序级放行规则。后者才是治本
3 网络自检 跑起来后到手表上点「测一下」,看电脑窗口有没有 >>> 收到 TCP 连接 <<<
7 查看防火墙状态 随时确认四条规则在不在、有没有阻止规则

网络自检的两种结果:

  • 收到连接 → 包能到电脑,问题在本机(程序没跑 / 端口被占)
  • 一个包都没收到 → 包没到,多半是路由器开了「AP 隔离」

三、功能

手表上全部是 58~64dp 的大按钮,两列排布,整页可滚动。

分类 功能
媒体 播放/暂停、停止、上一曲、下一曲、音量±、静音
显示 投图到电脑(全屏显示,按 Esc 或点一下关闭)
屏幕 实时屏幕镜像(默认 4 fps,可调帧率/画质/分辨率)、一键截屏并保存到手表
音频 放音到电脑(用系统 MCI 播放,不弹播放器窗口)
文件 发送文件到电脑 / 接收电脑上的文件
剪贴板 手表文字 → 电脑剪贴板;电脑剪贴板 → 手表(自动复制)
语音 让电脑语音播报指定文字(系统自带 TTS)
通知 在电脑托盘弹通知
电源 关机、重启、锁屏、睡眠、取消关机(二次确认)
其他 自定义命令(回显输出和退出码)、查看电脑系统信息
被动 电脑上复制东西时,手表会收到推送提示

四、安全设计

这是重点,请看完。

  1. 首次连接必须配对:电脑端生成 6 位随机码,只在窗口上显示,手表输入正确才能连。
  2. 令牌制:配对成功后发一个 32 位随机令牌,之后靠令牌免配对码登录。
  3. 未鉴权拒绝一切命令:没通过握手就发命令,服务端直接拒绝。
  4. 权限开关实时生效:窗口上可以随时关掉"自定义命令"、"电源操作"、"屏幕镜像",关掉后远程立刻执行不了。
  5. 无托盘但仍有可见性:按需求去掉了托盘图标;只要有设备连着, 屏幕右上角就会出现一条「已连接」提示条,可一键断开。
  6. 屏幕共享有强制提示(见下)。
  7. 不写注册表:所有数据放在程序目录下的 data/,绿色便携。
  8. 只在局域网:不联外网、不上传任何数据。想更安全就在防火墙里只放行内网段。

屏幕镜像的强制可见提示

只要有人在看你的屏幕,被控端屏幕右上角就会出现一条红色提示条:

┌──────────────────────────────────────────────────────────┐
│ ● 屏幕正在被共享   1 台设备正在观看 · 4.0 fps   [停止共享] │
└──────────────────────────────────────────────────────────┘

这条提示的规则:

  • 一定有:开始推流就出现,没有开关能关掉它。界面里也没有"隐藏提示"这类选项。
  • 本机可一键掐断:点提示条上的「停止共享」,立刻断开所有观看,并通知手表。
  • 截屏也会闪一下:单次截屏虽然短暂,同样会闪 2.5 秒提示。
  • 无人观看自动停:所有手表都断开后,抓屏线程立即结束,提示条消失,不留后台耗电。
  • 关掉权限立刻断:把窗口上的「允许屏幕镜像 / 截屏」取消勾选,正在进行的共享立刻被掐断。

这是本工具和"屏幕监视软件"的分界线:被控端永远知道、永远能停。

⚠️ 自定义命令 = 远程执行任意命令。这是你自己电脑上你自己开的功能, 但请务必:只在你信任的局域网里用,用完可以在窗口里关掉它。

安卓端权限

手表 App 在第一次启动时一次性把需要的权限全要了,之后选图片、选音频、发文件都不再弹窗:

权限 用途
INTERNET / ACCESS_NETWORK_STATE / ACCESS_WIFI_STATE 连局域网
READ_MEDIA_IMAGES / READ_MEDIA_AUDIO / READ_MEDIA_VIDEO(Android 13+) 列出手表上的媒体文件
READ_EXTERNAL_STORAGE(Android 12 及以下,maxSdkVersion=32) 同上

有权限时用内置选择器(带缩略图,直接在 App 里列文件);万一权限被拒,会自动回退到系统选择器, 所以功能不会因为拒权限而不可用。


五、连不上?先看这里

实测中「连不上」最常见的原因只有一个:Windows 防火墙没放行。

家用 WiFi 一般会被 Windows 归类成「公用网络(Public)」, 而公用网络的默认入站动作是阻止。如果没有显式放行规则, 手表的连接会被静默丢包 —— 表现就是「配对码明明对,但一直转圈连不上」。

真机上验证过:

Get-NetFirewallRule -Direction Inbound -Action Allow   ->  0 条规则
Get-NetConnectionProfile -InterfaceAlias WLAN          ->  Public

解决办法:被控端窗口会自动检测并显示一条橙色提示

防火墙未放行,手表连不上。   [一键修复]

点「一键修复」,同意一次管理员请求即可(放行需要管理员权限,这一步躲不掉)。 程序也会在目录下生成 放行防火墙.bat,可以右键「以管理员身份运行」。

手动执行等价于:

netsh advfirewall firewall add rule name="LAN Remote TCP" dir=in action=allow protocol=TCP localport=8765 profile=any
netsh advfirewall firewall add rule name="LAN Remote UDP" dir=in action=allow protocol=UDP localport=8766 profile=any

如果防火墙已放行还是连不上,依次检查:

  1. 手表和电脑是不是同一个 WiFi(不是手机热点、不是客人网络)
  2. 路由器有没有开 「AP 隔离」(开了的话同一 WiFi 的设备也互相不通)
  3. 电脑上是不是有 VPN / 加速器 / 虚拟网卡在抢占路由 (程序会优先选真实网卡地址;本机装 Tailscale 时 hostname 会解析到 169.254 链路地址,程序已按网段优先级排除了这种情况)
  4. 端口被别的程序占用(程序会提示「端口被占用」)

六、连不上时:用「设备诊断」

诊断已经合并进手表主程序了,不需要再装单独的 App。

手表上:主界面 ->「设备诊断」 -> 自动开始检测。

它会自动:

  1. 采集环境信息 —— 厂商/型号/安卓版本/API、屏幕像素与 density、 屏幕 dp 尺寸、字体缩放、是否被识别为手表、各权限的授予状态
  2. 采集网络参数 —— 连接类型、WiFi 名称/信号、本机所有 IPv4 地址与 前缀长度、DHCP 网关/掩码/DNS
  3. 真的跑一次局域网自动发现(UDP 广播 4 秒),列出找到的电脑
  4. 对找到的每台电脑做真实 TCP 连接测试,报告成功/失败与耗时
  5. 测完自动复制到剪贴板,直接到聊天窗口粘贴发给开发者即可

如果一台都没搜到,可以在诊断界面手动填电脑 IP 点「测一下」—— 它会分别做 UDP 单播探测 和 TCP 连接,能直接区分问题在哪:

结果 说明
单播有应答 + TCP 成功 网络是通的,问题在广播(路由器多播过滤 / AP 隔离)
单播有应答 + TCP 失败 广播被拦,且电脑防火墙拦了 TCP 8765 → 点被控端的「一键修复」
单播无应答 + TCP 失败 根本没通(不同网段 / 电脑没运行 / 防火墙全拦)

它刻意不收集什么:

  • IMEI、序列号、手机号、运营商
  • 联系人、短信、通话记录
  • 相册、文件列表、剪贴板内容
  • 位置坐标(定位权限只用于读取 WiFi 名称,不读经纬度)
  • 账号、已安装应用列表

报告内容全部显示在屏幕上,复制由使用者主动触发。

诊断与主程序在同一个 APK 里,共用同一份自动发现实现 (DiscoveryCore),所以不会出现「诊断说能通、主程序连不上」的假象。

底部还有一行「手动测电脑 IP」+「测一下」按钮——广播被拦时, 它会分别做 UDP 单播和 TCP 连接,直接告诉你问题在哪一段。


六点五、电脑端全部图形化(不依赖任何 .bat)

被控端窗口底部一行短按钮:

[ 接收 ]   [ 自检 ]   [ 说明 ]   [ 设置 ]        [ 退出 ]
按钮 作用
接收 打开收到的文件目录
自检 图形化网络自检(见下)
说明 窗口里直接看使用说明
设置 投图标题 / 播报音色 / 语速 / 音乐目录
退出 真正结束进程并释放端口

图形化自检

不再需要点任何 .bat。 自检直接读被控端自己的计数器, 所以被控端在跑的时候也能诊断(旧的控制台版本要抢端口,跑不了):

● 正常  一切正常,手表应该能连上。

--- 本机网络 ---
  192.168.2.64   [默认路由]
  >>> 手表上填这个 IP:192.168.2.64
  WiFi: 1602

--- 监听 ---
  控制端口 TCP 8765: 监听中
  发现端口 UDP 8766: 监听中

--- 收到过多少(关键)---
  自动发现请求: 12 个
  自检请求:     1 个
  TCP 连接:     3 次
  有数字说明手表的包能到达这台电脑

--- 防火墙 ---
  端口放行 TCP: 是
  程序级放行:   是  (LanRemote-Agent.exe)
  阻止规则:     0 条(针对本程序)

--- 结论 ---
  [OK] 一切正常,手表应该能连上。

窗口里还有「复制」和「一键修复防火墙」按钮。

手表上点「连不上?」,这台电脑会自动把自检窗口弹出来 (走 UDP,所以 TCP 被防火墙拦掉时也能到达)。


六点六、手表端:分页 + 37 个功能

连接后的界面是 6 个分页标签,每页最多 7 个按钮 —— 一屏放得下,完全不用滚动。

分页 功能
媒体 播放/暂停、停止、上一曲、下一曲、音量 +、音量 −、静音
屏幕 屏幕镜像、截屏、投图到电脑、放音到电脑、关显示器、设为壁纸
文件 发送文件、接收文件、剪贴板→电脑、取电脑剪贴板、剪贴板历史、打开文件夹
语音 语音播报、音色、朗读剪贴板、电脑音乐、弹通知
电脑 快捷命令、打开网址、进程管理、性能、磁盘、电量
系统 锁屏、睡眠、关机、重启、取消定时关机、定时关机、设备诊断

几个值得说的:

  • 电脑音乐 —— 列出电脑音乐目录里的音频,选一个直接在电脑上播
  • 音色 —— 列出电脑上所有 TTS 音色(中文 HuiHui / 英文 Zira 等),选一个
  • 进程管理 —— 按内存排序列出电脑进程,可以结束
  • 剪贴板历史 —— 电脑端保留最近 20 条剪贴板,手表上点一条就取回来
  • 设为壁纸 —— 把刚投过去的那张图设成电脑桌面壁纸
  • 快捷命令 —— 任务管理器 / 资源管理器 / CMD / 计算器 / 记事本 / 画图 / 控制面板 / 设备管理器
  • 定时关机 —— 15 / 30 / 60 / 120 分钟后关机,可取消

安全边界(都有测试):

  • 打开网址只允许 http / https,拒绝 file:// 之类
  • 播放本机音频只允许音乐目录内的文件
  • 快捷命令和文件夹都是白名单,不接受任意路径
  • 结束进程必须由用户在手表上确认

关于杀毒软件误报

先说结论

这个工具没有做任何免杀。 它会被某些杀软启发式报毒,这是真的, 我不打算靠混淆/加壳/加密去绕,因为那正是恶意软件的做法 —— 绕过去之后,你也分不清自己装的是不是真有毒。

真正能解决误报的路只有一条:代码签名(要买证书,见下)。

为什么会被盯上

特征 为什么杀软敏感 这是谁的需求
PyInstaller 打包 打包器的引导代码是启发式的重灾区 你要「多文件 exe,双击就跑」
写注册表 Run 键 自启动是持久化的典型手法 你要「开机自启」
无窗口后台常驻 隐藏进程是木马的常见形态 你要「全程静默」
监听端口 + 收指令 远控和被控端在行为上无法区分 这就是远控工具
提权改防火墙 改防火墙规则经常被拦 你要「黑终端一闪修防火墙」

这五条全是你明确要求的。 它们组合在一起,行为特征上和远控木马是一回事 —— 区别在于:配对码是你自己设的、认证是真的、你不会拿它去连别人的电脑。

我做了哪些合法的降误报

  1. --onedir 而不是 --onefile onefile 每次启动都往临时目录解压自己,这是最容易被判毒的行为之一。 onedir 不解压,启动也更快。

  2. --noupx 加壳压缩是杀软重点关注对象,明确关掉。

  3. 完整的版本信息 EXE 里写入了公司名、产品名、文件描述、版本、版权。 未签名二进制有正经的版本资源,比光秃秃的少一点可疑度, 也方便你在杀软里按「厂商 + 产品」加例外。

  4. 不做任何偷偷摸摸的事 没有自我复制、没有进程注入、没有内存加载、没有关闭杀软、 没有偷偷加防火墙例外。自启写注册表是你勾了勾选框才做的。

你遇到误报时怎么办

优先做成例外,不要关杀软。

被控端目录整个加进排除项即可(就是你放 LanRemote-Agent.exe 那个文件夹):

Windows 安全中心 → 病毒和威胁防护 → 管理设置
  → 排除项 → 添加或删除排除项 → 添加文件夹
  → 选 LanRemote-Agent 那个目录

加文件夹而不是单个 exe —— 因为 _internal\ 里的 dll/pyd 也可能被单独报。

真正根治:代码签名

有了签名,SmartScreen 和大部分杀软就不会再拦。需要:

  1. 买一张代码签名证书(OV 约 ¥1000-2000/年,EV 更贵但立刻获得 SmartScreen 信誉)
  2. 用 signtool 给 LanRemote-Agent.exe 和 _internal 里的 dll 签名
  3. 加时间戳(否则证书过期后签名失效)

买了证书之后告诉我,我把签名步骤加进构建脚本。

我查到的情况(本机)

这台机器上 Windows Defender 的按需扫描是坏的:

MpSmartConfigInitialize() failed (80070002)

Defender 的 PowerShell 模块(Get-MpComputerStatus 等)也不存在, 所以我没法在这台机器上给你一个权威的"报不报毒"结论。 我不会假装测过。

想自己确认的话,把 EXE 传到 VirusTotal 看一下 —— 那是最快的办法。


七、后台运行方式

按需求设计成没有托盘图标:

  • 双击 EXE → 弹出一个小窗口,上面一串 6 位配对码
  • 关掉窗口 → 程序继续在后台跑,仍然占着 8765 / 8766 端口
  • 任务管理器里能看到 LanRemote-Agent.exe
  • 再双击一次 EXE → 把已经在跑的那个窗口叫回来,不会重复起进程 (这里用 SO_EXCLUSIVEADDRUSE:Windows 上 SO_REUSEADDR 会允许 第二个进程绑同一端口,导致单实例判定失效 —— 实测踩到过)
  • 想彻底退出:窗口上点「退出」
  • 运行记录写在 data\运行日志.txt

保留了一条可见性:只要有设备连着,屏幕右上角会出现一条小提示条 (● 已连接:<设备名>,蓝色,带「断开」按钮);屏幕共享时它变红, 并带「停止共享」。没有托盘图标的前提下,这是让「有人正在控制这台电脑」 不被完全隐形的最低限度做法。空闲时它完全不显示。


八、常见问题

Q:手表连不上? A:先看被控端窗口上有没有橙色「防火墙未放行」提示,有就点「一键修复」。   没有的话,装附带的「遥控诊断」跑一次,把结果发给开发者即可定位。

Q:提示"电脑拒绝连接"? A:被控端程序没在运行(任务管理器里找 LanRemote-Agent.exe),或者端口被改了。

Q:提示"配对码错误"? A:配对码会变——点了"换一组"或者被控端重启过,就用窗口上最新的那组。

Q:下次打开还要输配对码? A:不该要。如果还要,说明上次配对没成功保存。

Q:托盘图标在哪? A:按需求没有托盘图标。关窗后程序继续后台运行;再双击一次 EXE 就能找回窗口。

Q:投图之后电脑上窗口关不掉? A:点一下图片,或者按 Esc。也可以把设置里的 image_timeout 改成秒数自动关闭。

Q:手表屏幕显示不全? A:界面是按 490×602 自适应做的:宽度小于 200dp 时自动切成单列并加大按钮。   别的分辨率改 MainActivity.java 里 adaptGridToScreen() 的阈值即可。


九、项目结构

LanRemote/
├── windows/                     # 被控端(Python)
│   ├── lanremote/
│   │   ├── protocol.py          # 协议常量 + 分块编解码
│   │   ├── config.py            # 数据持久化(设备令牌、设置)
│   │   ├── actions.py           # 投图/放音/媒体/剪贴板/电源/命令/TTS
│   │   ├── screen.py            # 屏幕捕获 + 帧流(Pillow,JPEG)
│   │   ├── discovery.py         # UDP 广播应答(手表不用输 IP)
│   │   ├── firewall.py          # 防火墙检测 + 一键提权放行
│   │   ├── instance.py          # 单实例锁(再次双击找回窗口)
│   │   ├── server.py            # TCP 服务 + 配对鉴权 + 命令分发 + 帧广播
│   │   └── ui.py                # 小窗口 + 状态提示条(无托盘)
│   ├── run_agent.py             # 启动入口
│   └── build_exe.ps1            # PyInstaller --onedir 打包
│
├── android/                     # 手表控制端(纯 Java,无第三方依赖)
│   ├── src/com/lanremote/watch/
│   │   ├── Json.java            # 自写 JSON(桌面 JVM 也能跑,便于联调)
│   │   ├── B64.java             # 自写 Base64(兼容老 Android)
│   │   ├── RemoteClient.java    # 协议客户端(纯 Java)
│   │   ├── DiscoveryCore.java   # 自动发现核心(纯 Java,可桌面联调)
│   │   ├── Discovery.java       # 安卓包装(MulticastLock)
│   │   ├── DeviceStore.java     # 设备令牌持久化
│   │   ├── MediaPicker.java     # 内置媒体选择器(免系统弹窗)
│   │   └── MainActivity.java    # 490×602 自适应大按钮 + 镜像面板
│   ├── AndroidManifest.xml
│   ├── res/                     # 图标 + 字符串
│   └── build_apk.ps1            # aapt2+javac+d8+apksigner 手工构建
│
├── diag/                        # 早期独立诊断 App 的源码(已合并进主程序,不再单独出包)
│   ├── src/com/lanremote/diag/
│   │   └── DiagActivity.java    # 环境采集 + 真实连通测试 + 一键复制
│   ├── AndroidManifest.xml
│   ├── res/                     # 图标 + 字符串
│   └── build_diag_apk.ps1       # 复用主程序的 Json/DiscoveryCore 一起编译
│
├── _tests/                      # 全部测试
│   ├── test_agent_protocol.py   # 被控端协议回归(69 项)
│   ├── check_layout.py          # 490×602 布局数学核算(22 项)
│   ├── test_indicator_visible.py# 屏幕共享强制提示(真实界面,9 项)
│   ├── test_simple_ui.py        # 小窗口/无托盘/后台常驻(真实界面,12 项)
│   ├── java/JavaClientTest.java # 跨语言联调(48 项)
│   ├── run_stub_server.py       # 无界面桩服务端
│   └── verify_all.ps1           # 一键全量验证(7 个阶段)
│
└── _build/                      # 构建辅助

十、协议(想自己扩展可以看)

TCP 长连接,每条消息一行 UTF-8 JSON(\n 结尾),二进制用 Base64 分块(256KB/块)。

握手

方向 消息
手表→电脑 {"cmd":"pair","code":"454534","deviceId":"watch-xxx","deviceName":"Watch"}
电脑→手表 {"ok":true,"token":"<32位>","serverName":"DESKTOP-XXX"}
手表→电脑 {"cmd":"auth","deviceId":"...","token":"..."}

命令(需鉴权)

cmd 参数 说明
ping - 心跳
info - 系统信息
media action playpause/stop/prev/next/volup/voldown/mute
image name,seq,last,data 投图(分块)
audio name,seq,last,data 放音(分块)
clip_set / clip_get text / - 剪贴板
say text 语音播报
notify title,text 通知
power action shutdown/restart/lock/sleep/abort
run command 自定义命令
file_push name,seq,last,data 上传文件
file_list - 列出接收目录
file_pull path 下载文件(分块回传)
screen_start fps,maxWidth,quality 开始实时屏幕镜像(1~15 fps)
screen_stop - 停止屏幕镜像
screenshot maxWidth,quality 单次截屏,回包里直接带 JPEG(base64)

自动发现(UDP 8766,让手表不用输 IP)

方向 报文
手表→广播 {"lanremote":"LANREMOTE_DISCOVER","proto":1}
电脑→单播 {"lanremote":"LANREMOTE_REPLY","proto":1,"name":"DESKTOP-X","port":8765,"version":"1.1.0"}

手表拿到回复后就知道电脑的 IP 和端口,直接连 TCP。与在哪个网段、 电脑有几张网卡都无关。

事件推送(电脑→手表,异步)

event 说明
clip 电脑剪贴板变化
file file_pull 的分块数据
frame 屏幕镜像的一帧(JPEG base64,带 w/h/size/ts)
screen_stopped 被控端本机掐断了共享
status 状态消息

注意三个容易踩的坑(都是实测踩过的):

  1. 分块上传时,中间块不回包,只在最后一块回一次。否则回复洪泛会导致后续命令消息错位。
  2. file_pull 分块之后还会有一条最终回执,客户端必须读走,不然会污染下一条命令。
  3. 镜像帧是高频事件,客户端读取线程必须把 frame 当事件异步处理, 绝不能让 frame 进入请求-应答队列,否则命令会全部超时。

十一、测试情况

跑 _tests\verify_all.ps1 一键全量验证:

项目 内容 结果
Python 被控端协议回归 配对/鉴权/媒体/剪贴板/投图/放音/文件/命令/电源/屏幕镜像/截屏/多设备 69/69 PASS
手表布局适配核算 490×602 在 density 1.0~3.0 下的按钮尺寸与文字容量 22/22 PASS
屏幕共享强制提示 真实 tkinter 界面 + Win32 EnumWindows 枚举窗口 9/9 PASS
小窗口与后台常驻 真实界面 + Win32:窗口尺寸、关窗后进程存活、双启动找回窗口、无托盘 12/12 PASS
Java 协议层编译 javac 目标 Java 8 PASS
Java ↔ 桩服务端 跨语言联调(含帧流、截屏、UDP 自动发现) 48/48 PASS
Java ↔ 打包后 EXE 端到端跑真交付物 48/48 PASS
交付 zip 解压重跑 解压到全新目录后运行 EXE 再跑一遍 PASS

测试中发现并修掉的真实 bug:

  1. 分块上传回复洪泛 —— 服务端给每个分块都回一次 ack,客户端只读一次,导致后续所有命令消息错位(run 收到的是 file_pull 的回包)。改为只在最后一块回包。
  2. 同名文件拉回旧版本 —— 同名文件第二次上传会存成 name_1.bin,但 file_pull("name.bin") 会拉到上一轮的旧文件。改为按名字匹配取最新的一份。(靠三方 SHA-256 比对才定位出来:长度完全一致,只有内容不同。)
  3. 损坏图片被当成成功 —— 实测发现传随机字节时 PIL 打开失败并返回错误;确认这是正确行为并加了回归用例。
  4. 自定义命令的控制台噪音 —— shutdown /a 的报错会打到 stderr,改成全静默。
  5. 镜像帧污染命令队列 —— 帧是高频事件,必须走事件通道;一旦混入请求-应答队列,所有命令都会超时。已在客户端读取线程里分流。

屏幕相关的安全属性,是被单独验证过的: _tests/test_indicator_visible.py 启动真实界面(不是桩),开始共享后用 Win32 EnumWindows 在系统窗口列表里查找提示条,确认:开始共享时出现 → 停止后消失 → 再次共享再出现 → 客户端断开后自动消失。这条属性不靠"看代码相信",靠枚举窗口实证。

未能验证的部分(如实说明):

  • 没有真机跑 APK。这台机器上没接安卓设备,也没装模拟器。APK 的验证做到了:构建成功、签名校验通过、aapt dump badging 结构正确、dex 里类齐全、协议层在桌面 JVM 上连真实服务端 35/35 通过。但界面在真实手表上的渲染效果没实测过。
  • 装到手表上如果布局有问题,改 adaptGridToScreen() 的阈值即可。

十二、自己重新构建

# 被控端 → 多文件 EXE
powershell -ExecutionPolicy Bypass -File windows\build_exe.ps1

# 手表端 → APK
powershell -ExecutionPolicy Bypass -File android\build_apk.ps1

# 全量验证
powershell -ExecutionPolicy Bypass -File _tests\verify_all.ps1

APK 用的是工作区里现成的工具链(starklink\toolchain:JDK 17 + Android SDK 34 + build-tools 34), 走 aapt2 → javac → d8 → zipalign → apksigner 手工链,不需要 Gradle。


十三、法律与责任

本工具是你自己的设备之间的局域网遥控工具。

  • 只用于你拥有或已获授权控制的电脑。
  • 在他人电脑上安装并隐藏运行,属于违法行为(《刑法》285/286 条)。
  • 本工具不提供任何隐藏、免杀、伪装能力,就是为了让它不能被用于那种场景。

请合法使用。

S
Description
ykxmz 主仓库(自动从 Gitee 同步)
Readme AGPL-3.0
67 MiB
Languages
Python 71.2%
Shell 14.4%
Java 7.3%
HTML 5.4%
PowerShell 1.3%
Other 0.4%