lanshare 是一个用 Rust 写的局域网文件互传工具。
在电脑上打开它,会出现一个原生桌面窗口,里面直接显示二维码、访问地址和收到的文件。 手机连同一个 Wi-Fi 扫一下二维码,浏览器里就能上传下载。
- 电脑端:桌面窗口,不用开终端
- 手机端:浏览器,不用装 App
为什么手机端还是浏览器?因为 iOS / Android 上装不了我们写的桌面程序。 浏览器是唯一一个所有设备都有的客户端 —— 这是绕不开的。 桌面窗口替代的是终端,不是浏览器。
传文件
- 扫码直达,二维码里已包含密码,扫一次就进
- 拖拽上传,也能直接
Ctrl+V粘贴截图 - 每个文件独立进度条、实时速度、剩余时间,可单独取消
- 上传与下载都支持断点续传
- 下载:HTTP
Range,大文件、音视频拖动都行 - 上传:大文件(≥ 8 MB)自动切成 4 MB 分片,断线后从断点继续而不是从零重来; 刷新页面后重新选择同一个文件也能接着传
- 下载:HTTP
- 多端实时同步:谁传了、谁删了,所有设备立刻看到
- 中文文件名全程无损
安全
- 默认开启密码保护,随机 6 位,窗口里显示得一清二楚
- 只有两条路能进:扫码,或者手动输地址后输密码
- 密码用恒定时间比较,防时序侧信道
- 登录限速:连续失败 8 次后锁定,逐次翻倍,上限 30 分钟
- 会话 Cookie 存的是随机会话令牌,不是密码本身
- 文件名净化,
../../etc/passwd这类路径穿越被挡掉
一次性文件
--ephemeral(界面可勾选):文件只存在临时目录,关掉就销毁- 正常关闭窗口、
Ctrl+C、kill、注销,都会触发销毁 - 唯一拦不住的是
kill -9;这种情况残留的目录会在下次启动时被清掉
其他
- 只读模式:只准下载,禁止上传与删除
- 不限制文件大小(默认)——上传 5 GB 实测内存恒定在 9 MB 左右,全程流式,
想限制时用
--max-size指定 - 深色界面,内置中文字体(不会出现方框)
- 完全离线:前端资源编译进二进制,不引用任何 CDN
sudo dpkg -i lanshare_0.1.0_amd64.deb或从源码构建:
cargo build --release
sudo install -m 0755 target/release/lanshare /usr/local/bin/lanshare窗口里会显示:
- 左侧:二维码、访问地址、访问密码
- 右侧:设置、收到的文件列表(可打开 / 删除 / 一键清空)
手机扫码 → 浏览器打开 → 拖文件上传。电脑这边文件立刻出现在列表里。
| 参数 | 说明 | 默认 |
|---|---|---|
-d, --dir <PATH> |
文件存储目录 | ~/Downloads/LanShare |
-p, --port <PORT> |
监听端口 | 8080 |
--password [<PWD>] |
设置访问密码;不带值则随机生成 | 随机 6 位 |
--no-auth |
关闭密码校验 | — |
--ephemeral |
一次性模式,退出即销毁文件 | 关闭 |
--no-gui |
只开服务不开窗口(服务器 / 脚本用) | 开窗口 |
--max-size <MB> |
单文件上限,0 为不限 |
0(不限) |
--readonly |
只读模式 | 关闭 |
--host <IP> |
绑定地址 | 0.0.0.0 |
# 用自己的密码
lanshare --password 我的密码
# 传完就销毁,不留痕迹
lanshare --ephemeral
# 关掉密码(只在完全可信的网络里这么做)
lanshare --no-auth
# 服务器 / 脚本场景:不开窗口,只跑服务
lanshare --no-gui -p 9000
# 只读分享一个目录
lanshare -d ~/Pictures --readonly
# 想限制单文件大小(默认不限)
lanshare --max-size 2048没有图形环境时(SSH、systemd)会自动退回终端模式,不需要手动加 --no-gui。
deb 包内置用户级 systemd 服务:
systemctl --user enable --now lanshare![]() |
![]() |
| 电脑端:桌面窗口(二维码 + 密码 + 文件列表) | 手机端:浏览器界面(扫码后打开) |
这个工具面向可信的局域网(家里、办公室)。请了解以下边界:
- 传输是 HTTP 明文。密码只是访问门槛,没有 TLS,同网段的人理论上能嗅探内容。 传敏感文件请先自行打包加密。
- 默认密码是 6 位数字(约 100 万种组合)。它足够挡住随手点进来的同事,
但挡不住有心人长期爆破 —— 限速能大幅拖慢,但不能根治。
要更强的安全性,请用
--password设一个长密码。 - 路由器开了 AP 隔离(公共 / 访客 Wi-Fi 常见)时设备之间无法互访, 这是网络策略,不是程序问题。
- 服务以你的用户身份运行,只能读写存储目录,不会执行上传的文件。
按顺序排查,绝大多数是第一条。
Linux 上 ufw 默认入站策略是 DROP。服务端一切正常、日志毫无异常,
但连接在到达进程之前就被内核丢掉了,表现就是手机一直转圈直到超时。
sudo ufw allow 8080/tcp # 换成你实际用的端口启动时 lanshare 会检测到这种情况并直接把命令打出来。
对比两边 IP 的前三段。手机在「设置 → WLAN → 当前网络」里能看到自己的 IP。
公共 / 访客 Wi-Fi 常见,会禁止无线设备互访。换个网络或开手机热点试试。
部分手机在 Wi-Fi 无外网时自动切回。临时关掉移动数据。
手机浏览器 ──HTTP/SSE──┐
├──▶ lanshare 桌面窗口 ──▶ 存储目录
另一台电脑 ──HTTP/SSE──┘ (内嵌 HTTP 服务)
- 存储目录即事实来源:启动时扫描建索引,每个文件分配随机 ID。 URL 里只有 ID,不泄露文件名,也天然兼容中文与重名。
- 上传先写
.lanshare-tmp/*.part,完成后原子rename, 失败或超限自动清理,不会留下半个文件。 - SSE 负责实时同步:连上先收一份完整快照,之后每次变更再收通知。
- 一次性模式的临时目录名带 PID,用
Drop+ self-pipe 信号处理器双重保证销毁; 启动时还会清理已退出进程留下的目录(严格只认自己的命名格式,不会误删别人的)。
cargo test # 205 项测试
cargo clippy --all-targets -- -D warnings # 静态检查,零告警
cargo fmt --all -- --check # 格式检查覆盖范围:
- 安全:路径穿越(
/与\两种写法)、控制字符、Windows 保留名、 超长中文名的 UTF-8 边界截断、密码比对、登录限速(阈值 / 递增 / 上限 / 来源隔离 / 成功清零 / 不影响正常轮询) - 存储:重名去重、空文件、中断上传清理、重启重新扫描
- 下载:
Range各种形态(0-99/500-/-100/ 越界)、 中文名的 RFC 5987 编码、inline与attachment - 接口:上传 → 列表 → 下载 → 删除全链路、超限清理、只读模式各项拦截
- 二维码:点阵边长与定位图案、静默区、逐格渲染比对、纯黑白、超长载荷
- 一次性目录:命名解析、拒绝外来同前缀目录、管道创建
- 地址刷新:地址未变时不广播、变化时地址与二维码一起重建、 启动时只有回环的过期地址能被后台循环自动纠正
- 分片续传:偏移校验与纠正(409 返回真实偏移)、断点接续后内容不乱、 声明大小与配置上限的拦截、放弃后不留残留、会话过期回收、会话数上限、 路径穿越文件名同样被净化、只读与密码模式下的拦截
另外用真实窗口与真实浏览器做过端到端验证:
- 桌面窗口在 Xvfb 下截图,逐格比对二维码 29/29 行与期望点阵完全一致
- 手机端路径用 Chrome DevTools 协议驱动:上传 250 KB 后字节完全一致、 SSE 推送到达、四条下载入口全部可用、移动端滑动删除可用
- 两种模式下
SIGTERM均已确认销毁临时文件 - 续传:真实 Chrome 上传 40 MB 时用 CDP 限速并在中途断网, 恢复后偏移序列显示从断点继续(未回到 0),md5 与源文件一致
./scripts/build-deb.sh # 构建并打包
./scripts/build-deb.sh --skip-build # 复用已有二进制产物:dist/lanshare_<版本>_<架构>.deb
脚本直接手写 DEBIAN/ 目录并用 dpkg-deb --build --root-owner-group 打包,
不依赖 debhelper 与 dh-cargo,也不需要 root。打包后自动校验必需路径、
二进制可执行性、md5sums 一致性,以及(若安装了)lintian。
src/
main.rs 入口:图形环境检测、一次性目录守卫
lib.rs 库入口(便于集成测试直接驱动路由)
cli.rs 参数定义
config.rs 配置解析、一次性目录生命周期
cleanup.rs self-pipe 信号处理器,保证 SIGTERM 也销毁文件
gui.rs 桌面窗口(egui)
controller.rs 服务启停(供窗口调用)
banner.rs 终端横幅与终端二维码
net.rs 局域网地址探测、二维码点阵
firewall.rs 防火墙检测与放行提示
store.rs 文件存储、文件名净化、原子落盘
upload.rs 分片续传上传的会话管理
state.rs 共享状态、文本片段、事件广播
server.rs 端口绑定与优雅关闭
error.rs 统一 JSON 错误响应
util.rs 随机串、Range 解析、下载文件名编码
routes/
mod.rs 路由组装
api.rs 业务接口
auth.rs 密码鉴权与登录限速
pages.rs 内嵌静态资源
web/ 手机端界面(零构建,编译期嵌入二进制)
tests/integration.rs
packaging/ deb 元数据、desktop、systemd 单元、图标
scripts/build-deb.sh
- 只支持 IPv4 局域网,不做公网穿透、IPv6 与内置 HTTPS
- 默认不限制文件大小;磁盘写满前不会主动拦截,超大文件请留意剩余空间
- 没有 mDNS,不能用
lanshare.local访问,需要看二维码或地址 - 文本片段保存在内存里,重启即清空
kill -9无法拦截(残留目录会在下次启动时清理)

