把一台闲置笔记本用作台式机的扩展副屏

Moonlight 串流 + 电源 / 网络唤醒 / 双系统自动化实战

本文记录把一台闲置笔记本(下称 LAPTOP)改造成主力台式机(下称 HOST)扩展副屏的完整过程。
目标不是”远程桌面”,而是物理意义上多一块显示器:鼠标从主屏滑过去就进入 LAPTOP,窗口可以拖过去,行为等同接了一根 HDMI。
并在此之上实现:HOST 开机即亮、关机即省电、切换系统自动跟随,日常零操作。


目录


0. 摘要

  • 协议:HOST 运行 Sunshine(主机端采集 + 编码),LAPTOP 运行 Moonlight(客户端解码 + 显示)。
  • 第二路输出的来源:HOST 上接入一个 HDMI 假负载(dummy plug,即俗称的”显卡欺骗”),使显卡多出一路输出;Sunshine 只采集这一路,不影响主屏。
  • 跨系统:HOST 为 Windows + Linux 双系统,两套系统各运行一份 Sunshine,客户端自动选择当前在线的那个。
  • 自动化:LAPTOP 上运行一个守护进程——HOST 在线时自动全屏拉流,离线时熄屏或挂起;HOST 开机时通过 Wake-on-LAN 唤醒睡眠中的 LAPTOP。
  • 四个关键难点:
    1. 混合显卡环境下的解码链路问题(queue overflow 死循环);
    2. WoL 组播发错网卡(魔术包从有线口发出,无法到达 WiFi 所在二层);
    3. 触摸板造成的虚假唤醒(挂起后约 15 秒自行唤醒);
    4. 双系统切换后的”僵尸流”(同机同 IP,客户端无法区分当前系统)。

1. 背景与动机

起因很朴素:HOST 平时只有一块 27 寸主显示器,而在某些工作流里(写代码放参考资料、看行情放副图、游戏放攻略等)确实需要第二块屏。但:

  • 再买一块显示器:占空间、要额外走线、成本也不低;
  • 手边正好有一台闲置的游戏本 LAPTOP,性能与屏幕都还能用,平时却在吃灰。

于是目标变成:让这台闲置笔记本的屏幕变成台式机的第二块显示器。

有几个具体的考量:

  1. 尺寸匹配。这台笔记本的内屏,竖过来之后,正好和 27 寸主屏在视觉上尺寸相称,并排放置不会显得突兀——这也是最终采用竖屏布局的直接原因。
  2. 它本质上是一块”自带操作系统的屏幕”。这一点很重要:它不像普通显示器那样只能被动显示,而是可以本地运行程序、可以切换模式、可以做更多事情。副屏只是它的第一层用途,后续还有不少扩展空间(后文第 8 节的”独立模式”就是其中一种)。

目标确定后,剩下的是把它做到”每天早上开机就在那儿、不用管”的程度。

1.1 为什么不用现成方案

“用一块屏当另一台机的副屏”其实有几条现成路径:Deskreen、spacedesk、Weylus、各种 VNC,甚至用采集卡。选择依据如下:

方案 优点 缺点
Sunshine + Moonlight 硬编硬解、低延迟、开源、可指定采集哪一路输出 配置相对繁琐
各类 VNC 部署简单 延迟高、颜色/刷新差、不适合当副屏
浏览器方案(Deskreen 等) 跨平台方便 延迟高、CPU 占用重
采集卡 延迟最低 需要额外硬件、线缆

结论:要”当副屏用而不别扭”,硬件编解码是刚需;在这个方向上,Sunshine/Moonlight 是相对成熟的组合。

1.2 名词说明

名词 说明
Sunshine 主机端软件,负责屏幕采集与编码。
Moonlight 客户端软件,负责接收、解码与显示。
假负载 / dummy plug 插在 HDMI 口上的小装置,内含一个假 EDID,使显卡认为”此处接有显示器”。
NVENC / NvFBC NVIDIA 的硬件编码 / 快速采集 API。
WoL(Wake-on-LAN) 网络唤醒,向睡眠中的主机广播魔术包使其唤醒。
Vulkan / VAAPI / NVDEC 显卡解码视频的几种后端,选择不当会导致卡顿乃至不可用。
Tailscale 组建虚拟内网的工具,使两台机器像在同一局域网,并自动尝试直连。
systemd Linux 的服务与进程管理器,负责开机自启与守护。

2. 硬件与拓扑

HOST(主力) LAPTOP(副屏)
角色 Sunshine 主机 / 采集编码 Moonlight 客户端 / 解码显示
系统 Windows + Linux 双系统 Linux(KDE Wayland)
显卡 单张 NVIDIA 独显 Intel 核显 + NVIDIA 独显(混合)
屏幕 27 寸主显示器(横屏) 内屏(竖屏)
网络 有线 + WiFi WiFi(另备有线口)
组网 Tailscale Tailscale

前提是两台机器网络互通。这里用 Tailscale 组了虚拟内网,好处是跨网段、出门也能用;但同局域网内有时存在端口隔离,直连会失败(见第 6、7 节)。

1
2
3
4
                   ┌──────────── Tailscale 虚拟内网 ────────────┐
HOST (采集+编码) ───┤ Sunshine ├─── LAPTOP (解码+显示)
└────────────────────────────────────────────┘
输出: [主显示器 横屏] [HDMI 假负载 竖屏(被 Sunshine 单独采集)]

需要注意:方向必须对齐。LAPTOP 内屏是竖屏,因此假负载也设为竖屏、位置也放在左侧。否则鼠标滑过去时方向与位置全部错位,手感会很别扭。


3. HOST 侧:构造一路虚拟输出并单独采集

3.1 接入假负载

显卡默认不会向”未接设备的接口”输出画面。接入一个 HDMI dummy plug(内含假 EDID)后,系统便认为多了一台显示器。此时 HOST 的显示布局为:

1
2
[ 假负载 竖屏 1080x1920 ]   [ 主屏 横屏 2560x1440 ]
(被串流采集) (日常使用)

在 Linux(KDE/X11)下用 xrandr 摆好:

1
2
# 将假负载(HDMI-0)转为竖屏,置于主屏(DP-4)左侧
xrandr --output HDMI-0 --mode 1920x1080 --rotate left --left-of DP-4

KDE 会记住该布局,下次登录自动恢复。若希望开机即生效、且不依赖 KDE,也可将其写入 kscreen 配置或一个 autostart 脚本。

3.2 让 Sunshine 只采集副屏

配置 sunshine.conf:

1
2
3
4
5
6
7
8
9
10
11
locale             = zh
output_name = HDMI-0 # 只采集假负载这一路,不采集主屏
capture = nvfbc # NVIDIA 快速采集(见 3.3)
encoder = nvenc
stream_audio = disabled
upnp = disabled
packetsize = 1200 # 见第 10 节 MTU
fec_percentage = 30
minimum_fps_target = 60
nvenc_preset = 1
nvenc_latency_over_power = enabled

逐项说明:

  • output_name:核心参数。只采集副屏,主屏刷新率等完全不受影响。
  • capture = nvfbc:使用 NVIDIA 采集。
  • encoder = nvenc:使用 NVIDIA 硬件编码。
  • packetsize = 1200:见第 10 节。
  • minimum_fps_target = 60:否则静态画面时可能降到 30fps,运动画面会显得不连贯。
  • stream_audio = disabled:作为副屏通常无需传输声音。

3.3 问题一:GeForce 上 NVFBC 默认被禁用

在消费级 GeForce 显卡上,NvFBC(快速采集 API)默认是禁用的。Sunshine 会退化为较慢、CPU 占用更高的 x11 采集方式,表现为”一开串流整机变卡”,且不会报错。

解决方式是使用社区补丁 nvidia-patch:

1
2
# 解锁 NVFBC / NVENC(附带 alpm hook,驱动更新时自动重打)
yay -S nvidia-patch

判断是否生效:查看 Sunshine 日志中的 Screencasting with NvFBC(出现即为已启用;若为 with X11 则未生效)。

3.4 问题二(Windows 专属):output_name 需要 device_id(GUID)

在 Windows 上写成:

1
output_name = \\.\DISPLAY2      # 不生效

Sunshine 不会报错,而是静默回退到采集主屏——表现为副屏上显示的是被缩放的主屏内容、上下有黑边,容易被误判为”分辨率不对”。

正确做法是取 Sunshine 启动日志中 Currently available display devices 里目标屏的 device_id(GUID):

1
output_name = {XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}

需要注意:Windows 与 Linux 的 output_name 格式完全不同(前者用 GUID,后者用 HDMI-0 这类连接器名)。双系统下两边的 sunshine.conf 是各自独立的,不能照抄。

3.5 网络与其它

  • 使用 Tailscale 名而非 IP 引用主机,避免 DHCP 变动。
  • 放行防火墙端口:47984 / 47989 / 48010 及若干 UDP 端口。
  • 双系统下 Windows 与 Linux 是两个不同的 Tailscale 节点(名称不同),客户端需能区分(见第 7 节)。

4. LAPTOP 侧:混合显卡环境下的解码问题

在混合显卡笔记本上,Moonlight 首次连接后往往会出现如下日志循环:

1
2
3
4
5
[SDL] Video decode unit queue overflow
[SDL] IDR frame request sent
[SDL] Waiting for IDR frame ← 无限循环(HEVC 时尤其明显)
[SDL] Video decode unit queue overflow
...

表现为画面卡死、花屏或延迟异常高。

4.1 成因

Moonlight 默认选择了 NVIDIA 独显进行 Vulkan 视频解码与渲染,但笔记本内屏挂在 Intel 核显上,导致每一帧都需要跨 GPU 拷贝;同时移动级 NVIDIA 显卡的 Vulkan 视频解码稳定性较差。

简言之:解码在一块 GPU、显示在另一块,帧在两者之间反复搬运,最终不堪重负。

4.2 解决:让解码与渲染全程留在核显,并采用 CPU 软解

1
2
3
4
5
6
7
8
9
10
11
12
# ① 只向 Vulkan 暴露 Intel 核显(关键一步)
export VK_DRIVER_FILES=/usr/share/vulkan/icd.d/intel_icd.json

# ② 使用 CPU 软解 H.264(在这套混合显卡上最稳定)
moonlight stream \
--display-mode fullscreen \
--resolution 1080x1920 --fps 60 --bitrate 20000 \
--packet-size 1200 \
--no-vsync --no-frame-pacing \
--video-decoder software \
--video-codec H.264 \
<HOST> Desktop

实测:修改后 queue overflow 归零,画面流畅;CPU 占用约 45%,对一台四核笔记本而言完全可承受。

4.3 细节

  • VK_DRIVER_FILES 必须指向 intel_icd.json,不要选到 intel_hasvk_icd.json(后者为 Haswell 老核显专用,会在新核显上报 No Vulkan devices found)。这一点曾以 grep intel | head -1 的方式选错,浪费了不少时间——因为它按字母序排在前面。
  • --resolution 需与副屏一致(此处为 1080x1920),否则会被缩放、影响清晰度。
  • --packet-size 1200 见第 10 节。
  • --no-vsync --no-frame-pacing 用于降低延迟;Wayland 下由合成器兜底,不会撕裂。
  • 软解占用 CPU:若 LAPTOP 同时还有别的负载,可安装 intel-media-driver 后改用核显 VAAPI 硬解。

这一条具有普适性:“解码在独显、显示在核显”是混合显卡笔记本的高频问题,凡使用 GPU 解码的软件都可能遇到;通用解法是避免跨 GPU。


5. 配对与证书

Moonlight 首次连接 Sunshine 需要配对:客户端生成一个 4 位 PIN,在 Sunshine 的 Web 后台(https://<host>:47990)中输入。

  • 配对是一次性的,之后会记住。
  • 双系统场景下,每套系统各配对一次即可。
  • 若忘记 Web 后台密码,可重置:
    1
    sunshine --creds <用户名> <新密码>

如需自动化,也可直接调用其 Web API:GET /api/pin 获取 pairing_id,再 POST /api/pin(带 pin / pairing_id / name)完成,无需手动点击。


6. 电源与网络唤醒自动化

目标:

  • HOST 在线 → LAPTOP 自动全屏拉流;
  • HOST 离线 → LAPTOP 熄屏或挂起以省电;
  • HOST 开机 → 唤醒睡眠中的 LAPTOP。

6.1 LAPTOP 上的守护进程

实现为一个循环(做成 systemd user 服务,随登录自启):

1
2
3
4
5
6
7
8
9
10
# 伪代码
while true; do
if 当前模式 != 副屏模式: sleep; continue # 独立模式下不动作
if HOST 在线:
if 未在串流: 启动 moonlight 全屏
else:
清理僵尸串流
若离线超过阈值 且 空闲: 熄屏 或 挂起
sleep 10
done

是否在线通过 tailscale status --json 判断。

6.2 熄屏与挂起的取舍

状态 功耗 HOST 开机能否自动连
熄屏(关显示,系统运行) 约 10W 可以:守护仍在运行,可立即连接
挂起(S3 睡眠) 约 1W 不能:需要先被唤醒(依赖 WoL)

因此,”极致省电”(挂起)与”开机可自动连”存在冲突:选择挂起,就必须具备唤醒能力。两种方式在实现中均可切换。

6.3 Wake-on-LAN:魔术包为何无效

唤醒睡眠中的机器,需要发送方广播一个魔术包(6 × 0xFF + 16 × 目标网卡 MAC)。实践中常失败,原因主要有两类。

问题三:魔术包发错网卡 / 跨网段

如果 HOST 与 LAPTOP 位于不同网段(中间隔着路由器),二层广播无法通过——WoL 是二层行为,路由器不转发广播。

更隐蔽的情况是:HOST 同时接入有线和 WiFi,默认路由走有线,于是魔术包从有线口发出,无法到达 LAPTOP 所在的 WiFi 二层:

1
2
3
HOST:   [有线 192.168.B.x]   [WiFi 192.168.A.x]   ← 默认路由走有线
LAPTOP: [WiFi 192.168.A.y]
└── 从有线发出的广播,无法到达 192.168.A.x

解决:将发送 socket 绑定到”与目标位于同一二层”的那个源地址:

1
2
3
4
5
6
# 找到与目标同网段的本地地址,绑定后再广播
src = <本机的 192.168.A.x 地址> # 关键:不是默认路由使用的接口
s = socket.socket(AF_INET, SOCK_DGRAM)
s.setsockopt(SOL_SOCKET, SO_BROADCAST, 1)
s.bind((src, 0))
s.sendto(magic_packet, ("192.168.A.255", 9))

最终实际采用的做法是:用一根网线将 LAPTOP 接入与 HOST 同一台路由器的 LAN 口,使两者处于同一二层,WoL 才稳定生效。“同一二层”是 WoL 的前提。

发送端(HOST)开机自动发送

  • Windows:计划任务,使用开机触发(BootTrigger)+ SYSTEM,不依赖登录;脚本先等待本机获得目标网段的地址,再循环发送数次(覆盖 LAPTOP 的睡眠窗口)。
    • 曾用”登录触发(onlogon)”,结果经常不触发(未登录时尤甚),改为开机触发后稳定。
  • Linux:systemd system 服务,开机执行;脚本同样先等接口就绪,再绑定源地址发送,避免开机时 WiFi 尚未连接而发出空包。

问题四:虚假唤醒

配置完成后发现:LAPTOP 挂起后约 15 秒便会自行唤醒,无法真正入睡,表面上像”熄屏”,实际在反复睡眠与唤醒。

排查唤醒源:

1
cat /sys/power/pm_wakeup_irq      # 每次挂起后唤醒,究竟是谁触发的

结果显示每次都是触摸板(一个 ACPI/I2C HID 设备,名称形如 MSFT0001:01),而非网卡。于是禁用其唤醒能力:

1
echo disabled | sudo tee /sys/bus/i2c/devices/i2c-<TOUCHPAD>/power/wakeup

并将其做成开机服务以持久化。禁用后机器才能真正入睡;更重要的是,这才是判定 WoL 是否成功的干净环境:

唤醒后 pm_wakeup_irq 含义
网卡的 PCIe PME 中断 由 WoL 唤醒
触摸板中断 由手动触碰或虚假唤醒触发

排查 WoL 前,应先将”非网卡的唤醒源”全部关闭,否则极易被”其实是手碰醒的”误导——它自己醒得比闹钟还勤。

6.4 小结

  • WoL 只能在同一二层内生效;跨网段不宜强求,可考虑路由器或静态 ARP 等手段。
  • 发送方需绑定到正确的源接口。
  • 接收方应先排除虚假唤醒源。
  • 成功与否以 pm_wakeup_irq 为准。

7. 双系统无缝切换

HOST 是双系统,因此对应两个 Tailscale 节点(例如 host-pc-win 与 host-pc)。客户端需要:

  1. 判断当前哪个节点在线;
  2. 连接它;
  3. 当”应连的节点”发生变化时,重连。

问题五:同机同 IP,客户端无法区分系统

双系统的两个操作系统在同一台机器、同一张网卡上,获取到的局域网 IP 是同一个。若用 LAN IP 连接,客户端无法判断当前连的是哪个系统;加之 Tailscale 的在线状态存在滞后,甚至观察不到清晰的”全部离线”窗口。结果是:

  • 从 Windows 切到 Linux(快速重启)时,指向旧系统的 Moonlight 进程僵留在原处未退出;
  • 守护进程发现”已有串流进程”,便不再重连——表现为切换后副屏一直黑屏或无法连接。

解决:

  • 使用每个节点唯一的 Tailscale IP(而非共享的 LAN IP)来标识”当前连接的系统”;
  • 守护进程每轮比较”Moonlight 实际连接的 IP”与”当前应连的 IP”,不一致即杀掉重连;
  • HOST”全部离线”时,同时清理僵尸进程。

由于 Tailscale 走的是直连(不经中继),使用 Tailscale IP 与 LAN IP 的性能差异可以忽略;为获得”可区分系统”这一能力,这一取舍是值得的。


8. 模式切换:副屏模式 / 独立模式

LAPTOP 不可能永远作为副屏——有时它本身就是一台普通笔记本。于是设计两个模式:

  • 副屏模式:守护进程生效(自动连接 / 省电);关闭锁屏(唤醒后免密码,避免打断自动连接)。
  • 独立模式:守护进程完全不动作;恢复锁屏(即一台正常笔记本,休眠后需密码)。

实现方式:

  • 一个状态文件 + 一个切换脚本(副屏 / 独立 / 循环);
  • 一个 KDE 面板小部件(左键循环,右键直接选择具体模式);
  • 切换时联动锁屏设置(修改 kscreenlockerrc 的 Autolock / LockOnResume);
  • 另提供一个 “立即重连” 的手动入口(面板右键 / 应用菜单 / 命令行),以备自动逻辑异常时使用。
1
2
副屏模式:HOST 在线 → 自动连;离线 → 熄屏;锁屏 = 关
独立模式:不动作; 锁屏 = 开(正常笔记本)

这也呼应了第 1 节的判断:它是一块自带操作系统的屏,因此”当副屏”与”当普通电脑”可以在同一个设备上按需切换。后续还能在此基础上做更多扩展。


9. 远程运维

整个过程基本是远程完成两套系统的配置的,依赖 Tailscale SSH:无需坐到 HOST 前,即可修改配置、查看日志、重启服务。

问题六:SSH 会话中无法使用图形认证代理

在 SSH 会话里执行 pkexec 做需要 root 的操作时,会报:

1
Error executing command as another user: No authentication agent found.

原因是 polkit 的图形认证代理运行在桌面会话中,而 SSH 会话不属于该 session。

解决:把需要 root 的操作打包成一个脚本,由用户在桌面上以 sudo bash xxx.sh 执行一次即可;或从桌面会话内部触发。

这也是自动化运维的常见边界:涉及交互式认证(sudo / polkit)时,最好将命令封装成脚本,交由人工确认执行。


10. 性能与调优

调优项 作用
--packet-size 1200 关键。Tailscale 的 MTU 为 1280,视频包超过会分片,进而卡顿;限制到 1200 后明显改善。
fec_percentage = 30 前向纠错,提升对 WiFi 丢包的容忍度(代价是略多带宽)。
minimum_fps_target = 60 防止静态画面降到 30fps。
nvenc_preset = 1 编码器最快档,降低编码延迟。
--no-vsync --no-frame-pacing 客户端减少缓冲,降低延迟。
--bitrate 局域网可提高码率换清晰度;WiFi 较弱则下调。
有线连接 LAPTOP 能接网线就接,可显著降低抖动,对”顺滑”帮助最大。

延迟来源是”采集 → 编码 → 网络 → 解码 → 合成 → 显示”这一整条链路。逐段削减缓冲(去 vsync / 帧平滑、避免跨 GPU、限制包大小),才能从”流畅”提升到”顺滑”。


11. 安全与取舍

这套自动化会触及若干安全默认值,需要明确其影响:

  • 关闭锁屏 / 免密码唤醒:副屏模式为便利而牺牲锁屏保护;独立模式会恢复。风险需自行评估。
  • 关闭触摸板唤醒:为避免虚假唤醒,代价是挂起后无法用触摸板唤醒(可用键盘或电源键)。
  • 开启 WoL:网卡在睡眠时保持可被魔术包唤醒。
  • Tailscale SSH / 免密登录:便于远程运维,但持有私钥者即可登入。
  • Web 后台密码:请设置足够强度。

总体原则:便利与安全存在权衡。将它们做成”按模式切换”——需要便利时享受便利,作为普通电脑使用时该锁就锁。


12. 问题汇总(现象 → 原因 → 解法)

现象 原因 解法
一开串流整机变卡 GeForce 上 NVFBC 被禁用,退化为 X11 采集 使用 nvidia-patch
副屏显示”缩放的主屏 + 黑边” Windows 的 output_name 写法错误,回退到主屏 使用 device_id GUID
客户端 queue overflow 死循环 混合显卡跨 GPU 解码 核显 VK_DRIVER_FILES + 软解
No Vulkan devices found 选错 ICD(hasvk) 选择 intel_icd.json
卡顿、微顿 Tailscale MTU 导致分片 --packet-size 1200
WoL 不生效 魔术包发错网卡 / 跨网段 绑定源地址;确保同二层
挂起后约 15 秒自醒 触摸板虚假唤醒 禁用其 power/wakeup
开关机 / 切换系统后连不上 僵尸流 + LAN IP 无法区分系统 唯一 Tailscale IP + 目标变化重连 + 全离线清理
Sunshine 报 Address already in use 后不监听 旧实例占用端口 启动前清理残留(pkill + sleep)
唤醒后没有网络 WiFi 在恢复时掉链 走有线 / resume 钩子重启网络
SSH 中 pkexec 报无认证代理 polkit 代理在桌面会话 打包成脚本,桌面 sudo bash 执行

上文真正有技术含量的部分,多半集中在这些”看起来没问题、实际暗中失败“的问题上:配置本身查几行文档即可,难的是定位这些故障。


13. 经验与结论

  1. 先明确”各对象应处于什么状态”,再动手。 省电、自动连接、可唤醒三者之间的关系决定了整体架构。
  2. 把不可见的状态变为可观测。 pm_wakeup_irq、tailscale status、Sunshine 日志中的实际分辨率——应以观测为准,而非猜测。
  3. 环境耦合是最大的障碍。 硬编码的 IP、设备名、路径,换一台机器便失效;若要复用或开源,需先参数化。
  4. 使用二分法排除干扰。 排查 WoL 时先关闭触摸板唤醒,问题立即清晰。
  5. “看起来相同”的对象需要可区分。 双系统同机同 IP 是典型案例,解决思路是引入唯一标识。
  6. 每一步都留可回退路径。 配置文件保留 .bak,服务可 disable,脚本可手动触发。

14. 附:组件与可复用要点

组件

  • 主机:Sunshine(LizardByte)、nvidia-patch
  • 客户端:Moonlight
  • 组网:Tailscale(直连 + SSH)
  • 显示:xrandr(X11)/ kscreen-doctor(KDE)
  • 自动化:systemd user/system 服务、Windows 计划任务、PowerShell
  • 唤醒:WoL(魔术包)+ pm_wakeup_irq 判据
  • 模式:KDE 面板小部件 + kscreenlockerrc

最值得单独复用的两点:

  1. 混合显卡笔记本上「核显渲染 + CPU 软解」以绕开解码问题;
  2. 「同一二层绑定源地址」的 WoL 正确发法,以及「关闭虚假唤醒源」的干净排查方法。

脱敏后的脚本骨架(示意)

1
2
3
4
5
6
7
# client-connect.sh —— 客户端一键全屏连接(自动选择在线节点)
export VK_DRIVER_FILES=/usr/share/vulkan/icd.d/intel_icd.json
moonlight stream --display-mode fullscreen \
--resolution 1080x1920 --fps 60 --bitrate 20000 \
--packet-size 1200 --no-vsync --no-frame-pacing \
--video-decoder software --video-codec H.264 \
"$(在线节点IP)" Desktop
1
# host-watch.sh —— 守护:在线自动连 / 离线省电 / 目标变化重连(伪代码见 6.1)
1
# wol.py —— HOST 开机向 LAPTOP 发送魔术包(关键:绑定到同一二层的源地址)

15. 生成声明

本文由 AI「大肥鱼」(DeepSeek)根据一次真实的折腾过程整理并撰写生成,并非作者本人所写。

文中所有主机名、IP、MAC、SSID、证书、路径等均已脱敏为占位符(如 HOST / LAPTOP / 192.168.A.x)。
内容按便于阅读的方式做了组织,技术结论基于实际测试;但因硬件、系统与网络环境而异,照搬未必生效,请以自身环境为准。
涉及第三方工具的用法,请以官方文档为准。

(全文完)