LocalSend 实战指南:本地文件分享的下载配置、防火墙设置与自签名证书协议解析
【免费下载链接】localsendAn open-source cross-platform alternative to AirDrop项目地址: https://gitcode.com/GitHub_Trending/lo/localsend
LocalSend 是一款免费开源的跨平台文件共享应用,允许你在局域网内安全地向附近设备传输文件和消息,全程无需互联网连接。本文以官方仓库中的波兰语版 README(support/readme/README_PL.md)为主线,完整覆盖下载渠道、兼容性矩阵、防火墙与路由配置、便携模式/后台启动等桌面高级用法,并结合 Rust 核心库源码深入解析其默认端口 53317 与“设备上即时生成自签名证书”的安全机制,帮助你在部署与排障时做到知其然更知其所以然。
什么是 LocalSend
LocalSend 是一个跨平台应用,设备之间通过REST API进行通信,所有数据均经由HTTPS 加密传输。与依赖外部中转服务器的即时通讯方案不同,LocalSend 不需要互联网连接,也不经过任何第三方服务器,因此本地传输速度快且稳定——文件只在你自己的局域网内流动。
项目采用“Flutter 前端 + Rust 核心”的双语言架构:应用 UI 层位于 app/lib,而协议、加密、发现与 HTTP 服务等核心能力沉淀在 Rust 包 packages/core 中,由 packages/localsend_isolates 通过 Flutter Rust Bridge 桥接给上层应用。
仓库中有一份模块依赖层级图,可作为理解整体结构的参考:
下载与安装
由于应用本身不具备自动更新能力,官方建议优先从应用商店或系统包管理器安装,以便后续获得更新。各平台可用的分发渠道如下(继承自波兰语版 README 的分发表):
| Windows | macOS | Linux | Android | iOS | Fire OS |
|---|---|---|---|---|---|
| Winget | App Store | Flathub | Google Play 商店 | App Store | Amazon 商店 |
| Scoop | Homebrew | Nixpkgs | F-Droid | ||
| Chocolatey | DMG 安装包(最新 Release) | Snap | APK(最新 Release) | ||
| EXE 安装包(最新 Release) | AUR | ||||
| 便携 ZIP(最新 Release) | DEB / TAR / AppImage(最新 Release) |
Windows 平台的二进制发行件经过代码签名,签名策略见 CODE_SIGNING.md。
兼容性矩阵
| 平台 | 最低版本 | 备注 |
|---|---|---|
| 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. | 依赖:Gnome 需要xdg-desktop-portal与xdg-desktop-portal-gtk;KDE 需要xdg-desktop-portal与xdg-desktop-portal-kde |
网络配置:防火墙与 AP 隔离
绝大多数情况下 LocalSend 安装后即可直接工作。但如果发送或接收文件失败,通常需要在防火墙上放行 LocalSend 的本地网络通信:
| 流量类型 | 协议 | 端口 | 动作 |
|---|---|---|---|
| 入站 | TCP, UDP | 53317 | 允许 |
| 出站 | TCP, UDP | 任意 | 允许 |
这个53317 端口并非文档约定俗成的数字,而是写死在代码中的默认值:Flutter 侧常量定义于 packages/localsend_isolates/lib/constants.dart(const defaultPort = 53317;),独立 CLI 工具中同样如此,默认端口常量声明在 cli/src/storage/config.rs(const DEFAULT_PORT: u16 = 53317;),CLI 的 cli/src/main.rs 也注明端口优先级为“命令行参数 > config.toml > 53317”。因此放行规则只需针对该端口的 TCP/UDP 双向流量。
除了防火墙,还需要确认路由器上的 AP 隔离(客户端隔离)已关闭。该选项默认通常为关闭状态,但部分路由器(尤其是访客网络)会默认开启;一旦开启,同一 SSID 下的设备之间将被禁止互访,LocalSend 的设备发现自然失效。
桌面端进阶用法
便携模式(Portable Mode)
自 v1.13.0 起支持。使用方法很简单:在与可执行文件同一目录下创建一个名为settings.json的文件(可以为空文件),应用就会改用该文件存储设置,而不是写入系统默认位置(注册表/用户配置目录),方便你用 U 盘随身携带整套配置。
从源码看,这一行为由 app/lib/util/shared_preferences/shared_preferences_portable.dart 实现:SharedPreferencesPortable继承自SharedPreferencesFile,其路径由buildSettingsPath计算——即“可执行文件所在目录 +settings.json”。值得注意的是_resolveExecutable()对Platform.resolvedExecutable的读取做了 try-catch 保护,以规避某些虚拟磁盘(如 ImDisk RAM 盘)上读取该属性会直接抛异常导致应用崩溃的问题;解析失败时会回退到当前工作目录。
在系统托盘后台启动
自 v1.15.0 起,使用--hidden标志即可让应用仅启动到系统托盘而不显示主窗口:
localsend_app.exe --hidden该标志的常量定义在 app/lib/util/native/autostart_helper.dart(const startHiddenFlag = '--hidden';),界面设置项中对应的文案为 “Autostart: Start hidden”(见 app/lib/gen/strings_en.g.dart)。在 v1.14.0 及更早版本中,行为有所不同:只有当autostart标志已设置且“隐藏启动”设置项开启时,应用才会在后台启动。
工作原理:REST API 与即时生成的自签名证书
README 指出:LocalSend 使用安全的通信协议,设备之间通过 REST API 交互,TLS/SSL 证书是在每台设备上即时(on the fly)生成的。这句话在 Rust 核心库中有直接对应——packages/core/src/crypto/cert.rs 中的generate_self_signed()生成一套完整的设备身份:
- RSA-2048密钥对,私钥以 PKCS#8 PEM 编码、公钥以 SPKI PEM 编码;
- 一张自签名证书,CN 固定为
LocalSend User,不携带 SAN——因为对端设备之间完全依靠证书指纹(而非域名)互相识别; - 证书的 SHA-256 指纹按大写十六进制编码(见 fingerprint_from_cert_der),即你在应用界面上看到的设备指纹格式;
- 有效期取 rcgen 默认值(1975–4096 年),意味着证书实际上永不过期,无需因时间原因轮换。
配套的verify_cert_from_pem/verify_cert_from_der负责在握手时校验对方证书:依次检查时间有效性、公钥是否匹配(若提供)、签名是否有效,任一失败都会给出对应的错误(“Time validity error” / “Public key mismatch” / “signature verification error”)。同文件内的单元测试(cert.rs#L157-L240)分别构造了签名被篡改、公钥不匹配、证书过期三种坏样本来验证这三条失败路径,是理解其校验逻辑的最佳示例。
承载 REST API 的 HTTP 服务端实现位于 packages/core/src/http/server,包含内部服务、v2/v3 版本端点以及面向浏览器下载的 web 端点;协议细节的官方规范在独立的 protocol 仓库中维护(主 README 有外链指引,本文不再重复外部链接)。
从源码编译
从源码构建 LocalSend 的步骤(继承自波兰语版 README 的 “Pierwsze kroki”):
- 安装 Flutter——建议直接用 fvm(Flutter Version Manager)安装,所需版本见 .fvmrc;
- 克隆 LocalSend 仓库;
- 执行
cd app进入app目录; - 执行
flutter pub get下载依赖; - 执行
flutter run启动应用。
注意:LocalSend 当前要求一个较旧的 Flutter 版本(由 .fvmrc 指定,当前仓库锁定为3.41.9)。系统全局安装的 Flutter 版本与要求版本不匹配,是导致编译失败的最常见原因。为保持开发一致性,项目使用 fvm 管理版本:安装 fvm 后,请统一用
fvm flutter代替flutter命令。补充一点波兰语版 README 未列出、但英文主 README 提到的前提:若需要构建 Rust 核心(isolates)部分,还需安装 Rust 工具链;仓库的 rust-toolchain.toml 锁定 channel 为1.97.1并附带 clippy。
以下为各平台的构建命令(继承自主 README 的 Building 章节,供维护者参考,均在app目录下执行):
Android
传统 APK:
flutter build apk用于 Google Play 的 AppBundle:
flutter build appbundleiOS
flutter build ipamacOS
flutter build macosWindows
传统构建:
flutter build windows本地 MSIX 应用包:
flutter pub run msix:create面向商店的 MSIX:
flutter pub run msix:create --storeLinux
传统构建:
flutter build linuxAppImage:
appimage-builder --recipe AppImageBuilder.ymlSnap 的打包说明位于独立的 localsend/snap 仓库(主 README 中有外链,此处不重复)。
参与贡献
项目欢迎任何形式的贡献,主要途径如下。
翻译
推荐通过 Weblate 平台管理翻译(主 README 中有平台入口外链);也可以自行 fork 仓库手动添加。翻译文件位于 app/assets/i18n 目录:编辑_missing_translations_<locale>.json或strings_<locale>.i18n.json来新增或更新译文。仓库中当前已有 60 余个语言的翻译 JSON 文件(如pl.json、zh-CN.json等)以及配套的_missing_translations_*.json缺漏清单。
注意:以@开头的字段不需要翻译——它们不会在应用中使用,仅用于说明文件信息或为译者提供上下文。
缺陷修复与功能改进
- 缺陷修复:发现问题后,请提交一个附带清晰问题描述与修复说明的 pull request;
- 功能改进:如果你有改进 LocalSend 的想法,请先创建 issue 讨论该改进的必要性。
更完整的规范见 CONTRIBUTING.md。
故障排查
继承自波兰语版 README 的排障速查表,按“发送端平台 / 接收端平台”定位问题:
| 问题 | 平台(发送端) | 平台(接收端) | 解决方案 |
|---|---|---|---|
| 设备不可见 | 任意 | 任意 | 确认已关闭路由器上的 AP 隔离;开启时设备间连接会被禁止 |
| 设备不可见 | 任意 | Windows | 确认网络类型被设置为“专用(private)”网络;Windows 对“公用”网络限制更严格 |
| 设备不可见 | macOS、iOS | 任意 | 可尝试在系统设置的“隐私”中切换“本地网络”权限开关 |
| 速度过慢 | 任意 | 任意 | 改用 5 GHz 频段;在两台设备上同时关闭加密 |
| 速度过慢 | 任意 | Android | 已知问题(源于 SAF 流读取的底层限制,主 README 中附有问题编号外链) |
若以上均不奏效,建议按顺序核对三件事:防火墙是否放行了 53317 端口的入站 TCP/UDP、路由器 AP 隔离是否关闭、两端是否处于同一二层网络(同 SSID 且未开启访客隔离)。
延伸阅读
- 波兰语版 README 原文:support/readme/README_PL.md
- 英文主 README(含分发渠道与构建细节):README.md
- Rust 核心库:packages/core/src/lib.rs,加密模块 packages/core/src/crypto/mod.rs,发现模块 packages/core/src/discovery/mod.rs
- Dart 应用入口:app/lib/main.dart
- 更新日志:CHANGELOG.md
【免费下载链接】localsendAn open-source cross-platform alternative to AirDrop项目地址: https://gitcode.com/GitHub_Trending/lo/localsend
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考