V2 文件/文本传输功能清单
一、文件传输
| 方向 |
触发方式 |
断点续传 |
进度显示 |
备注 |
| 服务端 → 客户端 |
文件管理器拖放/Ctrl+V |
✅ |
✅ |
支持大文件(>4GB) |
| 客户端 → 服务端 |
文件管理器下载 |
✅ |
✅ |
支持大文件(>4GB) |
| 客户端A → 客户端B (C2C) |
远程桌面 Ctrl+C/Ctrl+V |
✅ |
✅ |
自动捕获目标目录 |
二、文本传输
| 方向 |
触发方式 |
说明 |
| 服务端 → 客户端 |
远程桌面剪贴板同步 |
COMMAND_SCREEN_SET_CLIPBOARD |
| 客户端 → 服务端 |
远程桌面剪贴板同步 |
COMMAND_SCREEN_GET_CLIPBOARD |
| 客户端A → 客户端B (C2C) |
远程桌面 Ctrl+C/Ctrl+V |
自动粘贴 |
三、C2C 传输流程
四、协议命令
| 命令 |
值 |
用途 |
COMMAND_SEND_FILE_V2 |
85 |
V2文件数据包 |
COMMAND_FILE_RESUME |
86 |
断点续传响应 |
COMMAND_CLIPBOARD_V2 |
87 |
C2C剪贴板请求 |
COMMAND_FILE_QUERY_RESUME |
88 |
断点续传查询 |
COMMAND_C2C_PREPARE |
89 |
C2C准备接收通知 |
COMMAND_C2C_TEXT |
90 |
C2C文本传输 |
COMMAND_FILE_COMPLETE_V2 |
91 |
V2文件完成校验包 |
COMMAND_C2C_PREPARE_RESP |
92 |
C2C准备响应(返回目标目录) |
五、核心特性
- 断点续传: 基于 transferID + 文件特征匹配,支持传输中断后恢复
- 大文件支持: 使用 uint64_t 存储文件大小和偏移,突破4GB限制
- 自动目标目录: C2C传输自动捕获目标客户端当前焦点窗口的目录
- 自动粘贴: C2C文本传输完成后自动模拟 Ctrl+V 完成粘贴
- 版本协商: 能力位
CLIENT_CAP_V2 + 版本日期双重检测
- 文件完整性校验: 传输完成后发送 SHA-256 校验包,接收端自动验证
- 服务端开关: 参数菜单可控制是否启用 V2(默认关闭)
- 自动清理: 状态文件超过 7 天自动删除
5.1 文件完整性校验
每个文件传输完成后,发送端计算并发送 COMMAND_FILE_COMPLETE_V2 校验包:
工作流程:
- 发送端在发送文件数据同时计算 SHA-256
- 文件最后一个块发送完成后,发送
FILE_COMPLETE_V2 校验包
- 接收端在接收数据时同步计算 SHA-256(流式计算,无需重读文件)
- 收到校验包后对比哈希值,输出校验结果
支持的传输方向:
| 方向 |
校验位置 |
| 客户端 → 服务端 |
服务端校验 |
| 服务端 → 客户端 |
客户端校验 |
| 客户端A → 客户端B (C2C) |
服务端转发,客户端B校验 |
校验失败处理:
- 校验失败时自动删除损坏文件
- 日志输出期望和实际的 SHA-256 哈希值
断点续传与校验:
- 断点续传时无法使用流式 SHA-256(缺少历史数据)
- 自动切换为从文件重新计算完整 SHA-256
六、相关文件
| 文件 |
说明 |
common/commands.h |
协议命令定义 |
common/file_upload.h/cpp |
V2传输核心实现 |
client/KernelManager.cpp |
客户端主连接处理 |
client/ScreenManager.cpp |
客户端远程桌面会话处理 |
server/2015Remote/2015RemoteDlg.cpp |
服务端主逻辑 |
server/2015Remote/ScreenSpyDlg.cpp |
服务端远程桌面会话处理 |
server/2015Remote/CDlgFileSend.cpp |
文件传输进度对话框 |
七、使用说明
C2C 文件传输
- 打开两个远程桌面窗口(源A和目标B)
- 在源A上选中文件,按 Ctrl+C
- 按 X 切换到目标B
- 按 Ctrl+V,文件自动传输到B当前目录
C2C 文本传输
- 在源A上复制文本(Ctrl+C)
- 按 X 切换到目标B
- 在目标B的应用中按 Ctrl+V,文本自动粘贴
断点续传
- 传输中断后,重新执行相同操作
- 系统自动检测已传输部分,从断点继续
- 状态文件保存在
%TEMP%\FileTransfer\
- 状态文件超过 7 天自动删除
状态文件说明
| 后缀 |
用途 |
说明 |
.resume |
断点续传状态 |
记录 transferID、文件列表、已接收字节数 |
.recv |
C2C 接收方目录 |
记录目标客户端当前焦点窗口目录 |
.send |
C2C 发送方目录 |
记录源客户端剪贴板文件路径 |
所有状态文件统一存放在 %TEMP%\FileTransfer\ 目录,文件名格式为 {transferID}.{后缀}。
八、代码审查报告
8.1 审查范围
| 文件 |
改动行数 |
审查结果 |
common/commands.h |
+16 |
✅ |
common/file_upload.h |
+288 |
✅ |
SimplePlugins/file_upload.cpp |
核心实现 |
✅ |
client/KernelManager.cpp |
+294 |
✅ |
client/ScreenManager.cpp |
+360 |
✅ |
server/2015Remote/2015RemoteDlg.cpp |
+698 |
✅ |
server/2015Remote/CDlgFileSend.cpp |
+116 |
✅ |
server/2015Remote/context.h |
+34 |
✅ |
8.2 代码质量评估
优点
- 协议设计清晰 - 结构体使用
#pragma pack(push, 1) 确保跨平台对齐,注释详尽
- 版本兼容性 - V1/V2 协议共存,旧客户端仍可使用
- 能力协商机制完善 -
CLIENT_CAP_V2 能力位 + 版本日期双重检测
- 断点续传设计 -
transferID + fileIndex 组合键唯一标识,状态持久化
- 线程安全 - 使用
std::mutex 保护共享状态(g_fileStatesV2Mtx 等)
- 智能指针 -
std::unique_ptr 管理内存,RAII 处理文件句柄
- SHA-256 校验 - 使用 Windows bcrypt API,流式计算
待改进项
| 优先级 |
问题 |
位置 |
建议 |
| 🟠 中 |
路径穿越未验证 |
file_upload.cpp:712 |
GetRelativePath 添加 .. 检查 |
| 🟠 中 |
变量命名误导 |
file_upload.cpp:2463 |
utf8Name 实际是 ANSI,应改名 |
| 🟡 低 |
重复代码 |
KernelManager.cpp / ScreenManager.cpp |
C2C_TEXT 处理逻辑可提取公共函数 |
8.3 安全审查
| 检查项 |
状态 |
说明 |
| 缓冲区溢出 |
✅ |
有长度校验 if (len < sizeof(...) + nameLength + dataLength) |
| 认证校验 |
✅ |
使用 hash + hmac 验证 |
| 路径穿越 |
⚠️ |
GetRelativePath 未检查 .. 序列(实际风险低) |
| 客户端ID伪造 |
✅ |
通过 FindHost 验证客户端存在 |
| 文件句柄泄漏 |
✅ |
RAII 析构函数处理 |
| 整数溢出 |
✅ |
使用 uint64_t 支持大文件 |
路径穿越风险分析:
GetRelativePath 未过滤 .. 序列
- 实际风险较低:C2C 由服务端键盘钩子触发,非任意用户输入
- 建议后续版本加固
8.4 边界条件测试建议
| 场景 |
测试点 |
| 大文件 |
>4GB 文件传输和断点续传 |
| 网络抖动 |
传输中断后恢复 |
| 并发传输 |
多个 C2C 同时进行 |
| 客户端重启 |
.resume 文件恢复 + SHA-256 重算 |
| 目录结构 |
深层嵌套目录创建 |
| 空文件 |
0 字节文件传输和校验 |
九、提交评估
9.1 总体评估:✅ 可发布
| 指标 |
状态 |
说明 |
| 功能完整性 |
✅ |
C2C/断点续传/SHA-256 校验均已实现 |
| 编译通过 |
✅ |
无编译错误 |
| 向后兼容 |
✅ |
V1 协议仍可用,能力协商正确 |
| 崩溃风险 |
✅ |
无明显崩溃点 |
| 数据安全 |
✅ |
HMAC 认证、长度校验完善 |
9.2 问题分类
| 严重程度 |
数量 |
是否阻塞提交 |
| 🔴 致命 |
0 |
- |
| 🟠 中等 |
2 |
否 |
| 🟡 低危 |
1 |
否 |
9.3 后续改进建议
- 路径安全加固 - 在
GetRelativePath 添加 .. 过滤
- 重复代码重构 - 提取 C2C_TEXT 处理为公共函数
- 变量命名修正 -
utf8Name → ansiName
- 日志级别控制 - 添加 verbose 模式开关
审查日期: 2026-02-27