LocalSend 使用与源码解析:局域网安全传文件的技术原理、配置要点与常见问题排查
LocalSend 是一个免费开源的跨平台文件共享应用,允许在不依赖互联网和第三方服务器的情况下,通过本地网络与附近的设备安全地传输文件和消息。本文以仓库中的巴西葡语版 README(README_PT_BR.md)为主体,系统梳理其安装渠道、平台兼容性、防火墙与路由器配置、便携模式、隐藏启动、协议工作原理、源码编译与问题排查方法,并结合 packages/core 等 Rust 源码验证关键实现细节(53317 端口、UDP 多播发现、动态自签名 TLS 证书),读完后可完整掌握 LocalSend 从安装、网络配置到源码级原理的全链路知识。
一、项目定位:REST API + HTTPS 加密的本地通信
LocalSend 是一个跨平台应用,通过 REST API 和 HTTPS 加密实现设备间的安全通信。与依赖外部服务器的消息应用不同,LocalSend 不需要互联网连接或第三方服务器,因此是本地通信的一种快速、可靠的方案。
从源码结构看,这一描述与实现完全对应:
- 默认 HTTP 服务器端口与多播发现端口都是 53317,见 constants.dart 中的
const defaultPort = 53317;以及 multicast/mod.rs 中的pub const DEFAULT_PORT: u16 = 53317;——即“接收流量监听 53317(TCP+UDP)”的防火墙规则直接源自该常量。 - 当前协议版本为 2.2(constants.dart 中
const protocolVersion = '2.2';),该文件还给出了协议版本与 App 版本的对应表(1.0 → 1.0.0–1.8.0;1.0/2.0 → 1.9.0–1.14.0;1.0/2.1 → 1.15.0–1.17.0;2.2 → 1.18.0)。 - 设备发现基于 UDP 多播,默认多播组为
224.0.0.167(defaultMulticastGroup)。注释明确解释了选型原因:在 224.0.0.0/24 网段内,部分 Android 设备只能接收该 IP 范围内的 UDP 多播消息。默认发现超时为 500 毫秒(defaultDiscoveryTimeout),超时未收到响应即判定目标服务器不可用。
二、安装:应用商店与包管理器优先
由于应用没有自动更新功能,官方推荐从应用商店或包管理器下载安装(README 原文表格完整继承如下):
| Windows | macOS | Linux | Android | iOS | Fire OS |
|---|---|---|---|---|---|
| Winget | App Store | Flathub | Play Store | App Store | Amazon |
| Scoop | Homebrew | Nixpkgs | F-Droid | ||
| Chocolatey | DMG 安装器 | Snap | APK | ||
| EXE 安装器 | AUR | ||||
| ZIP 压缩包 | TAR 压缩包 | ||||
| DEB 包 | |||||
| AppImage |
关于分发渠道的更多说明可参考 CONTRIBUTING.md 的 distribution 章节;主 README.md 还补充了 Windows 二进制文件经过签名(代码签名政策见 CODE_SIGNING.md),且 Windows 7 的最后支持版本为 v1.15.4。
平台兼容性(最低版本):
| 平台 | 最低版本 | 备注 |
|---|---|---|
| Android | 5.0 | - |
| iOS | 12.0 | - |
| macOS | 11 Big Sur | 更老系统需借助 OpenCore Legacy Patcher 2.0.2(见上游 issue #1005) |
| Windows | 10 | 最后一个支持 Windows 7 的版本是 v1.15.4,未来可能有新版回移 |
| Linux | N.A. | 主 README 补充了依赖:GNOME 需要 xdg-desktop-portal 与 xdg-desktop-portal-gtk,KDE 需要 xdg-desktop-portal 与 xdg-desktop-portal-kde |
三、网络配置:防火墙放行与路由器 AP 隔离
大多数情况下 LocalSend 开箱即用。但如果发送或接收文件出现问题,可能需要配置防火墙以允许 LocalSend 通过本地网络通信:
| 流量类型 | 协议 | 端口 | 操作 |
|---|---|---|---|
| 接收(Incoming) | TCP、UDP | 53317 | 允许 |
| 发送(Outgoing) | TCP、UDP | 任意 | 允许 |
结合源码可以更深入理解这张表:
- 接收端:被接收的设备需要运行 HTTP 服务器(默认端口 53317)并监听 UDP 多播组
224.0.0.167:53317。multicast/socket.rs 中的bind_multicast_sockets会为每个通过过滤器的网络接口分别绑定一个 UDP socket(因为单个 socket 只能走一个接口发送),绑定失败的接口会被跳过而非导致发现整体失效——这也解释了为什么虚拟网卡异常时通常还能工作。 - 发送端:发现流程中发送方通过多播公告(announcement)感知对端,随后直连对端的 HTTP 服务器传输文件,因此出站流量端口是“任意”。
- 相关测试可参考 tests/multicast.rs 与 tests/discovery.rs,验证了多播绑定与设备发现流程。
除了防火墙,README 还特别提醒:请确认路由器上已关闭 AP 隔离(AP isolation)。它通常默认关闭,但部分路由器(尤其是公共网络/访客网络)可能开启;开启后设备之间的连接会被禁止。
四、配置技巧:便携模式与隐藏启动
便携模式(v1.13.0 引入)
在可执行文件所在目录创建一个名为 settings.json 的文件(内容可以为空)。之后应用会使用该文件存储设置,而不是默认的存储位置。
源码实现位于 shared_preferences_portable.dart:SharedPreferencesPortable 继承文件型 SharedPreferences 实现,buildSettingsPath 以可执行文件父目录为基准拼接出 settings.json 绝对路径;若 VM 无法解析可执行路径(例如某些虚拟磁盘上 Platform.resolvedExecutable 会抛 TypeError,见上游 issue #3021),则回退到当前工作目录。对应单测见 shared_preferences_portable_test.dart。
隐藏启动(v1.15.0 更新)
要启动应用并隐藏在系统托盘,使用 --hidden 参数,例如:
localsend_app.exe --hidden
注意版本差异:在 v1.14.0 及更早版本中,只有当 autostart 标志已设置且隐藏设置开启时,应用才会隐藏启动。
五、工作原理:动态生成的自签名 TLS 证书
LocalSend 使用安全的通信协议:设备之间通过 REST API 通信,所有数据经 HTTPS 加密传输,TLS/SSL 证书在每个设备上动态生成,以保证最高安全性。协议细节见上游独立的 LocalSend Protocol 文档仓库。
仓库源码印证了“动态生成”这一关键机制,见 crypto/cert.rs:
generate_self_signed生成 RSA-2048 密钥对与自签名证书(历史上 Flutter 应用端在 Dart 中也是同样的参数选择,保证两端兼容);- 证书附带 SHA-256 指纹(DER 格式),用于标识设备;
- 有效期使用 rcgen 默认值(1975–4096 年),证书实际永不过期;
- 证书主题名不携带任何信息(设备身份由指纹而非名称表达)。
这意味着每个设备都是一个“自己签发的 CA”:首次通信时对端需要通过指纹验证确认识别的是已知设备,而无需任何中心化的证书颁发机构或互联网服务。
六、从源码运行:Flutter + Rust 混合构建
README 的原始步骤如下:
- 安装 Flutter(直接安装或通过 fvm,版本要求见 .fvmrc)
- 克隆 LocalSend 仓库
- 执行
cd app进入应用目录 - 执行
flutter pub get下载依赖 - 执行
flutter run启动应用
[!NOTE] LocalSend 当前需要一个较旧的 Flutter 版本(在 .fvmrc 中指定),系统级 Flutter 版本与要求版本不一致可能导致编译问题。为使开发更一致,LocalSend 使用 fvm 管理项目 Flutter 版本;安装
fvm后,用fvm flutter代替flutter命令。
仓库现状佐证:
- 当前 .fvmrc 指定 Flutter 版本为 3.41.9;
- 主 README.md 的完整构建步骤还多了一步“安装 Rust”——因为
packages/core(协议核心)、packages/localsend_isolates/rust(FVM 桥接层)、cli/(命令行工具)均为 Rust 代码,由 cargokit 在 Flutter 构建时自动编译; app/pubspec.yaml中当前应用版本为1.18.2+64,与上文协议版本 2.2 对应(1.18.0 起使用 2.2)。
官方发行包构建命令(仅限维护者,需从 app 目录执行)可参考主 README 的 Building 章节:Android 用 flutter build apk / flutter build appbundle,iOS 用 flutter build ipa,macOS 用 flutter build macos,Windows 用 flutter build windows 或 flutter pub run msix:create [--store],Linux 用 flutter build linux 与 AppImage/Snap 方案。
七、参与贡献:翻译与 Bug 修复
翻译
推荐通过上游 Weblate 平台管理翻译;也可以 fork 仓库手动添加。翻译文件位于 app/assets/i18n 目录:编辑 _missing_translations_<locale>.json 或 strings_<locale>.i18n.json 来添加或更新翻译。当前该目录覆盖 ar、de、ja、ko、ru、zh-CN 等数十种语言。
注意:带
@前缀的字段不应翻译;它们不被应用以任何方式使用,仅是关于文件或给译者提供上下文的信息性文字。
生成后的 Dart 字符串类位于 app/lib/gen(strings_<locale>.g.dart),i18n 一致性有专门测试 i18n_test.dart 保障。
Bug 修复与改进
- Bug 修复:发现 bug 请提交 pull request,清晰描述问题与修复方式;
- 改进建议:有改进想法请先创建 issue 讨论其必要性;
- 更多细节见 CONTRIBUTING.md。
八、问题排查(Troubleshooting)
完整继承 README 的排查表,并给出对应机制说明:
| 问题 | 发送端平台 | 接收端平台 | 解决方案 |
|---|---|---|---|
| 设备不可见 | 任意 | 任意 | 确认路由器已关闭 AP 隔离。若开启,设备间的连接会被禁止 |
| 设备不可见 | 任意 | Windows | 将网络配置为“专用(private)”网络。Windows 在网络被配置为“公用”时限制更严格 |
| 设备不可见 | macOS、iOS | 任意 | 尝试在系统设置“隐私”中切换“本地网络”权限 |
| 速度过慢 | 任意 | 任意 | 使用 5 GHz 频段;在两个设备上关闭加密 |
| 速度过慢 | 任意 | Android | 已知问题(上游 saf_stream 库相关) |
结合源码机制补充理解:
- “设备不可见”本质上要么是多播公告未送达(AP 隔离、Windows 公用网络防火墙、macOS/iOS 本地网络权限关闭),要么是对端 HTTP 服务器不可达(防火墙未放行 53317)。由于发现依赖每个接口上
224.0.0.167:53317的多播监听(multicast/mod.rs),任何阻断该 UDP 组播的策略都会让设备“隐身”; - “速度过慢”建议关加密的原因在于本地传输的瓶颈通常在 Wi-Fi 本身,而加解密会额外消耗 CPU(接收端 Android 上已知受 SAF 流限制影响);
- 应用内置了调试辅助页(debug_page.dart、discovery_debug_page.dart、http_logs_page.dart),可用于查看发现日志与 HTTP 日志,辅助定位上述问题。
九、小结
LocalSend 的核心技术路线可以概括为:UDP 多播(224.0.0.167:53317)负责设备发现,HTTPS REST(默认端口 53317,自签名 RSA-2048 证书 + SHA-256 指纹标识设备)负责数据传输,全程零互联网依赖。对使用者而言,关键配置只有三件事:防火墙放行 53317(TCP+UDP)入站流量、关闭路由器 AP 隔离、在受限平台(Windows/ macOS/iOS)确认本地网络权限;对开发者而言,源码入口在 packages/core(Rust 协议核心)、packages/localsend_isolates(Flutter 桥接层)与 app/lib(Flutter 应用层),配合 .fvmrc 指定的 Flutter 3.41.9 即可从源码完整构建。
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