Deskflow实现原理
你了解这个项目吗,是GitHub上的开源项目GitHub - deskflow/deskflow: Share a single keyboard and mouse between multiple computers. · GitHub
了解。
Deskflow 是一款跨电脑共享键盘和鼠标的开源软件,可以让你用一套键鼠控制多台电脑。
例如,你的 Windows 和 Linux 电脑各自连接显示器,鼠标移到屏幕边缘就能切换到另一台电脑,键盘输入随之切换,还能共享剪贴板。
它支持 Windows、macOS 和 Linux,默认启用 TLS 加密;
它不传输屏幕画面。
我也看了你当前目录里的源码,主要结构是:
| 目录 | 作用 |
|---|---|
src/apps | GUI、核心程序和后台服务入口 |
src/lib/gui | 图形界面 |
src/lib/server、client | 服务端与客户端逻辑 |
src/lib/net | 网络通信 |
src/lib/platform | 各操作系统相关实现 |
src/unittests | 单元测试 |
本地代码采用 C++20、Qt 和 CMake。如果你准备研究源码、编译运行或者修改功能,我们可以直接基于这个目录继续。
它的原理是什么,为什么可以实现一个电脑作为服务端,让另一台电脑作为客户端,使用服务端的键盘和鼠标?
它的核心原理是:服务端捕获键鼠事件,通过网络发送给客户端,客户端再调用操作系统接口,模拟对应的键鼠操作。
传输的是“按下了哪个键、鼠标移动到哪里”等事件数据。
电脑 A:服务端 电脑 B:客户端
物理键盘、鼠标
↓
操作系统接收输入
↓
Deskflow 捕获输入事件 ─── 网络传输 ──→ Deskflow 解析事件
↓
调用系统输入接口
↓
B 上的应用接收输入
服务端怎么知道你按了什么?
操作系统提供了监听键鼠输入的接口。
以 Windows 为例,Deskflow 使用 SetWindowsHookEx 安装低级键盘和鼠标钩子,监听按键按下、松开、鼠标移动、点击和滚轮等事件。
对应实现在 [MSWindowsHook.cpp (line 670)]
(D:/QtCode/deskflow-master/deskflow-master/src/lib/platform/MSWindowsHook.cpp:670)。
比如你按下 A,程序就可以获取这个按键及其修饰键状态,例如是否同时按着 Shift、Ctrl。
怎么决定控制哪台电脑?
服务端维护着各台电脑的屏幕布局,以及“当前正在控制的电脑”。
假设配置成:
[电脑 A] [电脑 B]
鼠标在 A 屏幕内时,输入作用于 A。
鼠标到达 A 的右边缘、满足切换条件后,Deskflow 将当前控制目标改为 B,并计算鼠标进入 B 屏幕的位置。
控制 B 期间,服务端会拦截需要转发的输入,避免同一次操作也作用到 A 的普通应用。
相关判断和事件分发主要在 [Server.cpp (line 1611)]
(D:/QtCode/deskflow-master/deskflow-master/src/lib/server/Server.cpp:1611)。
网络里发送的是什么?
它把事件编码成自己的协议消息,例如:
键盘:按下 A、松开 A、按下 Ctrl
鼠标:移动到 (300, 200)、左键按下、滚轮滚动
实际传输使用二进制字段,并不是上面这样的文字。
源码中的鼠标移动消息标识是 DMMV,键盘按下消息根据协议版本使用 DKDN 或 DKDL。
客户端主动连接服务端,默认使用 TCP 24800 端口。
连接建立后,服务端就可以持续向客户端发送输入事件。“客户端主动连接”并不妨碍它接收服务端发来的控制数据。
客户端为什么能让其他程序收到这些操作?
因为操作系统也提供了生成模拟输入的接口。
例如 Windows 的 SendInput 可以向系统输入流注入键盘和鼠标事件。
Deskflow 收到远端事件后,进行按键映射、坐标处理等转换,再调用这些接口。
项目中的相关实现可以看到 [MSWindowsDesks.cpp (line 93)]
(D:/QtCode/deskflow-master/deskflow-master/src/lib/platform/MSWindowsDesks.cpp:93)。
所以,当 B 上的文本编辑器获得焦点时,你在 A 的键盘上打字,B 的编辑器就能收到输入。
模拟输入仍受操作系统权限和安全规则限制。
跨平台也是相同思路:网络层传递统一的事件,各平台代码负责把事件转换成本系统的输入操作。 因此,服务端和客户端不需要使用相同的操作系统。
所以,某种程度上,我如果只希望共用一套键盘,则可以自己实现一个简单的版本。让我当前的键盘操作都发送给客户端对应的电脑,然后让它做出响应,就实现了一版简单的共用键盘软件。
对,你理解得很准确。如果只做两台电脑之间的键盘转发,完全可以自己实现一个简化版。
基本流程就是:
A 捕获键盘事件 → 网络发送 → B 接收事件 → 模拟键盘输入
以两台 Windows 电脑为例,可以用:
- A 端:
WH_KEYBOARD_LL键盘钩子捕获事件。 - 通信:TCP 连接,发送按键编号、按下或松开等信息。
- B 端:调用
SendInput注入键盘事件,交给当前获得焦点的应用处理。
是的,现有的程序太复杂了,对我来说很不友好
确实,Deskflow 要兼顾跨平台、多屏切换、剪贴板同步和各种系统差异,代码复杂度远超“把键盘输入转发到另一台电脑”这个需求。
如果你的目标是自己理解、修改和使用,可以把第一版缩小到:
- 两台 Windows 电脑,一台连接键盘,另一台接收输入。
- 手动填写 IP,通过 TCP 连接。
- 用一个热键切换“控制本机 / 控制远端”。
- 只转发键盘的按下、松开事件。
- 断线后自动回到本机,并释放远端按键。
建议单独写一个小项目,这样输入捕获、网络通信、输入模拟三部分都能看得清楚。
先把基本功能跑通,再按实际需要增加界面或其他功能。
openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构
更多推荐


所有评论(0)