LocalSend 使用与实现指南:局域网安全文件传输的设置、HTTPS 协议原理与源码构建实战
LocalSend 是一款不依赖互联网、在本地网络上安全共享文件与消息的免费开源跨平台应用。本文基于该项目的韩语版 README(support/readme/README_KO.md)展开,覆盖系统要求、防火墙与网络设置、可携带模式与隐藏启动等关键配置,并深入解读其 HTTPS 自签名证书与 UDP 多播发现协议在源码中的落地实现,最后给出从零编译运行与逐平台打包的完整命令。
一、LocalSend 是什么
LocalSend 是一个通过 REST API 与 HTTPS 加密在设备之间安全收发文件的跨平台应用。与依赖外部服务器(云端中继、账号体系)的传输类应用不同,LocalSend 完全工作在局域网内:
- 不需要互联网连接,也不需要任何第三方服务器;
- 所有数据经 HTTPS 加密传输,每台设备各自生成 TLS/SSL 证书;
- 定位为“快速且可靠的近场通信方案”。
这一描述直接来自韩语版 README 的「정보」章节(support/readme/README_KO.md),与英文版(README.md)的 About 章节一一对应。
二、下载渠道与系统要求
由于应用本身没有自动更新功能,官方建议通过应用商店或包管理器下载,以便获得后续版本。各平台可用渠道如下:
| 平台 | 渠道 |
|---|---|
| Windows | Windows Store、Winget、Scoop、Chocolatey、EXE 安装包、Portable ZIP |
| macOS | App Store、Homebrew、DMG 安装包 |
| Linux | Flathub、Nixpkgs、Snap、AUR、DEB、TAR、AppImage |
| Android | Google Play、F-Droid、APK 直装 |
| iOS | App Store |
| Fire OS | Amazon 商店 |
各平台最低版本要求(「요구 사항」表):
| 平台 | 最低版本 | 备注 |
|---|---|---|
| Android | 5.0 | — |
| iOS | 12.0 | — |
| macOS | 11 Big Sur | 更老的 macOS 需借助 OpenCore Legacy Patcher 2.0.2 |
| Windows | 10 | 最后一个支持 Windows 7 的版本是 v1.15.4,未来可能回填更新版本 |
| Linux | N.A. | 依赖 xdg-desktop-portal 及各桌面环境对应实现 |
此外,Windows 平台的二进制文件经过代码签名,签名策略详见 CODE_SIGNING.md。
三、设置:防火墙、AP 隔离与两个实用开关
大多数情况下 LocalSend 开箱即用,但在文件收发受阻时,通常需要检查以下三类网络/系统设置。
3.1 防火墙端口规则
「설정」章节给出的放行规则为:
| 流量类型 | 协议 | 端口 | 操作 |
|---|---|---|---|
| 入站 | TCP、UDP | 53317 | 允许 |
| 出站 | TCP、UDP | 任意 | 允许 |
这个 53317 端口不是文档中凭空出现的数字,它在核心协议库中被定义为多播发现端口与默认 HTTP 服务端口,两者取值相同。在 packages/core/src/multicast/mod.rs 中:
/// The default multicast port, identical to the default HTTP server port.
pub const DEFAULT_PORT: u16 = 53317;
CLI 一侧同样以 53317 为默认值,可在 config.toml 中覆盖,见 cli/src/storage/config.rs 与 cli/src/main.rs(/// Port of the HTTP server [default: config.toml, else 53317])。因此防火墙只需放行 53317 的入站流量,即可同时覆盖“设备发现”与“HTTPS 传输”两条链路。
3.2 路由器 AP 隔离
文档特别提醒:务必确认路由器上关闭了 AP 隔离(AP Isolation / Client Isolation)。该功能通常默认关闭,但在部分路由器尤其是公共网络的访客 SSID 上常被开启。一旦启用,同一 Wi-Fi 下的设备之间将被禁止直接通信,LocalSend 自然互相“看不见”。
3.3 可携带模式(Portable Mode)
v1.13.0 引入。只需在可执行文件所在目录放置一个 settings.json 文件(内容可以为空),应用便会把配置写入该文件,而不是默认的持久化路径。
从源码结构看,这一行为的实现位于 app/lib/util/shared_preferences/shared_preferences_portable.dart:SharedPreferencesPortable 继承 SharedPreferencesFile,启动时通过 buildSettingsPath() 将路径解析为可执行文件父目录下的 settings.json;当虚拟机无法解析可执行文件路径时(如某些虚拟磁盘场景),还会回退到当前工作目录。这解释了“文件可以放在 exe 旁边即可生效”的机制,也为排查“设置没有存到预期位置”类问题提供了依据。
3.4 以隐藏方式启动(Start hidden)
v1.15.0 更新。若希望应用启动后直接隐藏到系统托盘(不显示主窗口),使用 --hidden 命令行参数:
localsend_app.exe --hidden
v1.14.0 及更早版本则要求同时满足两个条件:设置了 autostart 标志,且“隐藏启动”设置项已开启。
源码印证:--hidden 是一个具名常量,在 app/lib/util/native/autostart_helper.dart 中定义为 const startHiddenFlag = '--hidden';,Linux 平台的自启动 .desktop 文件生成逻辑中,当 startHidden 为真时会把它追加到 Exec= 命令行末尾——这正是“隐藏设置与 autostart 组合生效”的代码级证据。
四、工作原理:REST API + 每台设备一张自签名证书
「작동 원리」章节的核心表述是:LocalSend 使用一套基于 REST API 的安全通信协议,所有数据经 HTTPS 传输,且 TLS/SSL 证书在每台设备上动态生成,以最大限度保证安全。官方协议规范维护在独立的 protocol 文档仓库中(README 外链,本文不展开)。
结合核心库源码,可以从三个层面理解这套机制:
1. 设备发现:UDP 多播广播
在 packages/core/src/multicast/mod.rs 中定义了协议使用的多播组:
/// It is inside `224.0.0.0/24` because on some Android devices this is the only
/// IP range that can receive UDP multicast messages.
pub const DEFAULT_MULTICAST_GROUP: Ipv4Addr = Ipv4Addr::new(224, 0, 0, 167);
pub const DEFAULT_MULTICAST_GROUP_V6: Ipv6Addr =
Ipv6Addr::new(0xff12, 0, 0, 0, 0, 0, 0xfd3a, 0xe420);
IPv4 组特意选在 224.0.0.0/24 网段,是因为部分 Android 设备只在该范围内能可靠接收 UDP 多播;IPv6 组则是一个 link-local 作用域的瞬态组,作为 v2.2 协议之上的扩展并行广播。设备通过携带自身指纹、HTTP 服务端口、协议类型(HTTPS 或 HTTP)等信息的多播消息宣告自己;由于单条数据报可能丢失,宣告会以 100ms / 500ms / 2000ms 的间隔重复发送(ANNOUNCE_DELAYS)。
2. 身份标识:自签名证书 + 指纹
在 packages/core/src/crypto/cert.rs 的 generate_self_signed() 中:
- 生成 RSA-2048 密钥对,与 Flutter 应用历史上用 Dart 生成的证书保持兼容;
- 自签名证书 CN 为
LocalSend User,不携带 SAN——因为设备之间仅凭证书指纹互相识别,证书名本身不承载信息; - 有效期极长(1975 至 4096 年),实际上不会过期,也无需按时间轮换。
设备的指纹即该证书 DER 编码的 SHA-256 十六进制值(大写格式,同文件 fingerprint_from_cert_der)。多播消息中携带该指纹,用于过滤自身回环包,也用于接收端校验对方身份是否与历史配对记录一致。
3. 数据传输:本地 HTTPS
发现阶段拿到对端 IP 与端口后,实际的文件收发通过指向 https://<ip>:53317/api/... 的 REST 请求完成。packages/core/src/http/client/url.rs 中的单元测试可直接看到 URL 形态,例如 https://192.168.1.1:53317/api/localsend/v2/register(设备注册)与 .../api/localsend/v2/info(信息交换)。由于双方都持自签名证书,信任锚点是配对时人工确认的指纹,而非公共 CA 体系。
五、从源码开始:获取并运行 LocalSend
「시작하기」章节给出的六步编译流程为:
- 安装 Flutter——直接安装,或使用 fvm(所需版本见 .fvmrc);
- 安装 Rust 工具链;
- 克隆 LocalSend 仓库;
cd app进入应用目录;flutter pub get拉取依赖;flutter run启动应用。
重要提示(原文以警示块给出):LocalSend 目前锁定的是特定 Flutter 版本,若系统与项目要求的 Flutter 版本不匹配,会出现各种构建错误。项目使用 fvm 管理 Flutter 版本以保持一致性;安装 fvm 后,请统一用
fvm flutter替代flutter命令。
当前仓库 .fvmrc 中实际锁定的版本为 Flutter 3.41.9,构建前可据此核对环境。Rust 侧另有 rust-toolchain.toml 约束工具链版本,app 目录通过 flutter_rust_bridge 将 Dart 与 Rust 核心(packages/core)连接起来。
六、构建发布产物(面向维护者)
韩语版 README 目录中列出了 빌드(Building)各平台条目,对应的构建命令与英文版一致,均在 app 目录下执行,且仅面向维护者/打包者:
Android
flutter build apk # 传统 APK
flutter build appbundle # 用于 Google Play 的 AppBundle
iOS
flutter build ipa
macOS
flutter build macos
Windows
flutter build windows # 传统 EXE
flutter pub run msix:create # 本地 MSIX 应用
flutter pub run msix:create --store # 应用商店就绪的 MSIX
Linux
flutter build linux # 传统构建
appimage-builder --recipe AppImageBuilder.yml # AppImage
Snap 渠道的说明维护在独立的 localsend/snap 仓库(README 外链);各平台的自动化打包脚本也可参考 support/scripts 目录,例如 compile_windows_msix_store.ps1、compile_android_apk.sh 等。
七、故障排查速查表
「문제 해결」章节整理了最高频的几类问题,原表完整继承如下:
| 问题 | 平台(发送方) | 平台(接收方) | 解决方法 |
|---|---|---|---|
| 设备不可见 | 任意 | 任意 | 确认路由器已关闭 AP-Isolation;若开启,设备间连接将被禁止 |
| 设备不可见 | 任意 | Windows | 将网络类型设为“私有(개인)”网络;公共网络下 Windows 限制更严格 |
| 设备不可见 | macOS、iOS | 任意 | 在系统设置的“隐私”中切换“本地网络”权限开关 |
| 速度过慢 | 任意 | 任意 | 改用 5 GHz 频段;在两台设备上同时关闭加密 |
| 速度过慢 | 任意 | Android | 已知问题(源自依赖的 SAF 流式读写插件,上游已有 issue 跟踪) |
结合第四节的原理可以补充理解:前三个“不可见”问题都发生在发现阶段(多播收不到或系统拦截网络访问),而后两个“速度慢”发生在传输阶段(无线信道质量或 Android 存储流式 I/O 瓶颈),排障时应先区分卡在哪个阶段。
八、参与贡献:翻译与缺陷修复
翻译
LocalSend 通过 Weblate 平台管理多语言翻译,也可以 fork 仓库直接提交。翻译文件位于 app/assets/i18n 目录,按语言组织,例如:
_missing_translations_<locale>.json(如 _missing_translations_zh_CN.json):待补译条目清单,仓库中覆盖 zh-CN、ja、ko、ar、ru 等数十个语言;- 各语言主翻译文件(如 ko.json、ja.json)。
注意:以 @ 开头的字段不是翻译对象——它们不会在应用中显示,只是给译者提供上下文或文件说明信息,请勿翻译。编译后的字符串类由 app/lib/gen 下的 strings_<locale>.g.dart 承载。
缺陷修复与改进
- Bug 修复:发现缺陷后,直接提交 Pull Request,并清晰描述问题现象与修复方式;
- 功能改进:先创建 Issue 讨论改进的必要性,再动手实现。
更完整的流程规范见 CONTRIBUTING.md,项目行为约定另见 AGENTS.md 与 CLAUDE.md。
小结
这篇文档的价值在于把 LocalSend 的“使用面”(防火墙 53317 端口、AP 隔离、settings.json 可携带模式、--hidden 参数)与“实现面”(UDP 多播发现组、RSA-2048 自签名证书与 SHA-256 指纹、/api/localsend/v2 REST 端点)串成一条完整链路:遇到“设备不可见”时查发现链路与网络策略,遇到“速度/加密”问题时查传输链路,动手编译时严格遵循 fvm 锁定的 Flutter 版本。所有关键结论均可在仓库对应源码路径中复核。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0623
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00