RustDesk 源码导读:自托管远程桌面快速上手完整指南
【免费下载链接】rustdeskAn open-source remote desktop application designed for self-hosting, as an alternative to TeamViewer.项目地址: https://gitcode.com/GitHub_Trending/ru/rustdesk
RustDesk 源码解析:这是一个用 Rust 编写的开源远程桌面工具,TeamViewer 的自托管替代方案,你的 ID、密码和画面数据全部自己掌控。本文带你看懂它屏幕传输、网络打洞、远程输入三条主线是怎么实现的。
项目速览:这份代码值得读在哪
RustDesk 做的事一句话概括:在你的电脑上输入别人机器的 ID 和密码,就能实时看到并操控它的屏幕,附带文件传输、剪贴板同步和端口转发。
它的源码值得读,因为一个进程里同时塞进了「被控端服务」和「控制端客户端」——src/server/ 负责在你本机采集屏幕、执行远端输入,src/client.rs 负责连到对方并把画面渲染出来。而且它把远程桌面里最脏的几块活——NAT 打洞、跨平台键盘鼠标模拟、多后端屏幕采集——全用 Rust 重写并摊开给你看,比读一篇协议文档直观得多。
三分钟跑起来:先装什么、敲哪两条命令
前置条件:Rust 工具链(cargo)、C++ 编译器,以及 vcpkg 管理的 C 依赖。屏幕编码依赖 libvpx、opus、aom 这几个 C 库,必须先装好:
vcpkg install libvpx libyuv opus aom VCPKG_ROOT=$HOME/vcpkg cargo run第一条命令把视频/音频编解码的 C 依赖装进 vcpkg,第二条从仓库根目录编译并启动程序。
首次编译要下载并编译 C 库,等十几分钟是正常的。启动后你应该看到一个主界面:显示本机 ID 和一个临时密码,「连接」输入框里填对方的 ID 就能发起会话。默认走 RustDesk 官方公共服务器,不自建服务器也能用。
核心功能拆解:画面、连接、输入三条线
画面是怎么传过去的:采集 → 编码 → UDP 发送
你看到的是远端屏幕在窗口里实时刷新,像看视频。
负责这块的是 libs/scrap(屏幕采集,按平台切 X11、Wayland、DXGI、DMA-BUF 等不同后端)和 src/server/video_service.rs(服务线程里负责取帧、编码)。内部运作:服务端循环抓屏,用 libvpx 或 AV1 编码成视频流,通过 KCP(基于 UDP 的可靠传输)发出;对端在 src/client/io_loop.rs 里收帧、解码、渲染。整个链路和你在浏览器看直播是同一套思路,只是换成了私有通道。
连接是怎么建立的:先 TCP 打洞,打不通再中继
你看到的是输入 ID、密码,稍等一下就接通了。
负责这块的是 src/rendezvous_mediator.rs(约 1000 行)。内部运作:启动时双方都向注册/中继服务器报到,一方发起连接后,服务器把两个地址互换,双方各自尝试 TCP 打洞;任何一边打不通,就降级走服务器中继。读懂这个文件,网络层就通了。
远端输入和剪贴板是怎么同步的
你看到的是在远端机器上动鼠标、敲键盘,还能跨机复制文本和拖文件。
负责的是 libs/enigo(按平台模拟键盘鼠标事件)和 libs/clipboard(文件与文本剪贴板);接收端在 src/server/input_service.rs 和 src/server/clipboard_service.rs 把收到的指令落到系统上。
上图展示一台机器粘贴的文件出现在另一台机器上,就是 clipboard 库加服务端接收逻辑配合的结果。
关键模块深读:src/client.rs 的三个职责
src/client.rs 是项目里最大的单文件(4000 多行),核心是 Peer 结构体。打开它盯住三处:
- new():初始化 Peer,把音频、视频、文件传输、剪贴板等通道一次性挂起来;
- start():对外的异步入口,负责连服务器、完成密码和二次验证,然后进入主循环;
- 事件分发:对端发来的每类消息——视频帧、输入事件、set_option 配置同步——都被路由到各自的处理函数。
配合入口文件 src/main.rs 看更清楚:
fn main() { #[cfg(all(windows, not(feature = "inline")))] unsafe { winapi::um::shellscalingapi::SetProcessDpiAwareness(2); } if let Some(args) = crate::core_main::core_main().as_mut() { ui::start(args); } common::global_clean(); }这段是桌面版入口:core_main() 在 src/core_main.rs 里解析命令行、决定是否启动内建服务端,然后 ui::start(args) 拉起界面,退出前 global_clean() 统一回收资源。
如何改变它的行为:配置都写在哪
RustDesk 没有传统意义上的配置文件,设置是键值对,通过 Config::set_option 存到用户目录下的本地存储,你在设置面板里改的每一项(分辨率、默认编码器、端口转发)最终都走这条路径,客户端侧的同步逻辑在 src/client.rs 的 set_option 处理分支里。
想改变两个最常见的行为:
- 换成自建服务器:在设置面板「ID/Relay」栏填自己部署的 hbbs/hbbr 地址即可,相关加载逻辑在 src/custom_server.rs,改完重启生效;
- 换编译形态:Cargo.toml 的 feature 开关(flutter、inline 等)决定用哪套 GUI 和是否内联资源,vcpkg 里装的依赖决定编码路径。
源码阅读路线:按这个顺序读三组文件
- 先读 src/main.rs 加 src/core_main.rs,把「进程怎么起、参数怎么解析」钉死;
- 再读 src/rendezvous_mediator.rs,打通「连接怎么建立、打洞怎么降级」这条网络主线;
- 最后分头读两端:控制端 src/client.rs 和 src/client/io_loop.rs,被控端 src/server.rs、src/server/video_service.rs、src/server/input_service.rs。读到这一步,整条「采集—传输—渲染—注入」闭环就闭环了。
常见踩坑:编译慢、起不来、卡顿
- 编译报错或巨慢:九成是 vcpkg 依赖没装全或 VCPKG_ROOT 没指对,先确认 vcpkg install 四个库全部成功,再重跑 cargo run。
- 启动后没有窗口:新版桌面 GUI 走 Flutter,仓库里 src/ui 的 Sciter 界面已按官方说明废弃,别按老教程去找 sciter 库,除非你明确要构建旧版 UI。
- 远程画面卡顿:传输走 UDP 的 KCP,打洞失败降级中继后会受服务器带宽限制。确认两端能否直连,或干脆自建中继服务器。
顺带提醒:官方专门画了防钓鱼示意图,遇到自称「RustDesk 客服」要你输密码的窗口,一律按诈骗处理。
【免费下载链接】rustdeskAn open-source remote desktop application designed for self-hosting, as an alternative to TeamViewer.项目地址: https://gitcode.com/GitHub_Trending/ru/rustdesk
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考