# UpdateTool **Repository Path**: bogezzb/UpdateTool ## Basic Information - **Project Name**: UpdateTool - **Description**: No description available - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-07-17 - **Last Updated**: 2026-07-20 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # UpdateTool 网络升级工具 - 支持IPv4/IPv6的客户端/服务端文件同步系统 项目源代码:https://gitee.com/bogezzb/UpdateTool.git ## 项目简介 UpdateTool 是一个基于 C++ 开发的网络文件升级工具,采用客户端/服务端架构,通过 IPv4/IPv6 TCP 协议实现文件的增量更新。工具会自动扫描文件、计算 MD5 值、比较差异,并下载需要更新的文件。 ## 功能特性 - **IPv4/IPv6 网络通信**:客户端与服务端支持 IPv4 和 IPv6 双协议通信 - **增量文件同步**:基于 MD5 校验的增量更新,仅下载缺失或变更的文件 - **多线程服务端**:服务端采用线程池模式(最多8个工作线程)处理高并发请求 - **智能内存缓存**:服务端对已下载文件进行内存缓存,支持最大内存限制(默认200MB),超过时按LRU策略释放,10分钟未访问自动释放 - **服务端配置文件**:支持通过 `server_config.json` 配置缓存大小和指定扫描路径 - **客户端超时重连**:客户端支持动态超时调整和断线自动重连,网络恢复后可继续更新 - **单实例运行**:客户端和服务端均只允许一个运行实例,防止重复启动 - **跨平台支持**:支持 Windows 和 Linux 平台 - **大文件分段传输**:超过 256MB 的大文件采用分段发送方案,每块 256MB,需客户端确认后再发送下一块,支持 4GB 以上超大文件 - **客户端接收缓冲区优化**:设置 SO_RCVBUF 为 8MB,防止高速数据传输时连接重置 ## 软件架构 ``` ┌─────────────────────────────────────────────────────────────────┐ │ 服务端 (Server) │ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────────────┐ │ │ │ 监听线程 │→│ 任务队列 │→│ 线程池 (8工作线程) │ │ │ └─────────────┘ └─────────────┘ └─────────────────────┘ │ │ │ │ │ │ ▼ ▼ │ │ ┌─────────────┐ ┌─────────────┐ │ │ │ 文件扫描模块 │ │ 文件缓存模块 │ │ │ │ (MD5计算) │ │ (10min过期) │ │ │ └─────────────┘ └─────────────┘ │ └─────────────────────────────────────────────────────────────────┘ │ ▼ (IPv4/IPv6 TCP, 端口 9528) ┌─────────────────────────────────────────────────────────────────┐ │ 客户端 (Client) │ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────────────┐ │ │ │ 配置读取 │→│ 本地文件扫描 │→│ 远程文件列表获取 │ │ │ │ (config.json)│ │ (MD5计算) │ │ │ │ │ └─────────────┘ └─────────────┘ └──────────┬──────────┘ │ │ │ │ │ ▼ │ │ ┌──────────────────────────────────────────────────────────┐ │ │ │ 文件比较与下载 │ │ │ │ - 本地不存在 → 新增下载 │ │ │ │ - MD5不一致 → 更新覆盖 │ │ │ │ - MD5一致 → 跳过 │ │ │ └──────────────────────────────────────────────────────────┘ │ └─────────────────────────────────────────────────────────────────┘ ``` ## 构建方法 ### 依赖环境 - CMake 3.16+ - C++11 编译器(MSVC/GCC/Clang) ### 编译步骤 ```bash # 创建构建目录 mkdir build && cd build # 生成构建文件 cmake .. # 编译(Windows使用MSBuild,Linux使用make) cmake --build . --config Release ``` 编译产物输出到 `build/bin/bin/` 目录: - `UpdateToolServer.exe` / `UpdateToolServer` - 服务端程序 - `UpdateToolClient.exe` / `UpdateToolClient` - 客户端程序 ## 使用说明 ### 1. 服务端部署 #### 1.1 目录结构要求 将服务端程序部署到**包含所有待分发文件的根目录**下: ``` 服务端根目录/ ├── UpdateToolServer.exe # 服务端程序 ├── app.exe # 待分发文件1 ├── config.ini # 待分发文件2 ├── data/ # 待分发子目录 │ ├── file1.txt │ └── file2.dat └── docs/ # 待分发子目录 └── readme.txt ``` **文件更新范围说明:** - 服务端会扫描其所在目录及**所有子目录**下的文件 - 生成的文件列表包含相对路径和 MD5 值 - 隐藏文件和系统文件也会被扫描 #### 1.2 启动服务端 ```bash # 直接运行服务端程序,默认监听 9528 端口 ./UpdateToolServer # 指定端口启动 ./UpdateToolServer 8080 # 查看帮助信息 ./UpdateToolServer -h ``` **命令行参数:** | 参数 | 说明 | 默认值 | |------|------|--------| | 端口号 | 指定服务端监听端口,范围 1-65535 | 9528 | | -h / --help | 显示帮助信息 | - | 服务端启动后会: - 扫描当前目录及子目录下所有文件 - 计算每个文件的 MD5 值 - 在指定端口监听客户端连接 - 按 Ctrl+C 停止服务 #### 1.3 服务端配置文件(可选) 在服务端程序所在目录创建 `server_config.json` 文件: ```json { "max_cache_memory": 209715200, "include_paths": [] } ``` | 配置项 | 类型 | 默认值 | 说明 | |--------|------|--------|------| | `max_cache_memory` | int | 209715200 (200MB) | 最大缓存内存大小(字节),超过时按LRU策略释放最早访问的文件 | | `include_paths` | array | [] | 指定的文件/文件夹路径列表,为空时扫描整个目录 | **配置说明:** - **缓存内存限制**:服务端会将常用文件缓存到内存中以提高响应速度,当缓存总大小超过 `max_cache_memory` 时,会自动释放最早访问的文件。单个文件超过最大缓存限制时,不会加载到内存,而是从磁盘动态读取。 - **指定扫描路径**:通过 `include_paths` 可以指定需要同步的文件或目录: - 如果列表为空或配置文件不存在,服务端会扫描整个目录 - 如果指定了路径,服务端只扫描这些路径下的文件 - 路径可以是文件或目录,如果是目录会递归扫描其下所有文件 - `server_config.json` 配置文件本身不会被包含在文件列表中(避免被客户端更新) **配置示例:** ```json { "max_cache_memory": 104857600, "include_paths": [ "bin/", "lib/", "config/app.ini" ] } ``` --- ### 2. 客户端部署 #### 2.1 目录结构要求 将客户端程序部署到**需要被更新的目标文件夹根目录**下: ``` 客户端根目录(需要被更新的目录)/ ├── UpdateToolClient.exe # 客户端程序 ├── config.json # 客户端配置文件(必须与程序同目录) ├── app.exe # 已有的旧版本文件 ├── config.ini # 已有的旧版本文件 └── data/ # 已有的旧版本子目录 └── file1.txt ``` **客户端文件放置规则:** - `UpdateToolClient.exe` 和 `config.json` **必须放在同一目录** - 该目录即为客户端的**工作根目录** - 更新时会将文件下载到该目录下,保持与服务端相同的目录结构 - 更新完成后,客户端不会自动删除自身 #### 2.2 配置客户端 在客户端程序所在目录创建 `config.json` 文件: ```json { "server_ip": "::1", "server_port": 9528 } ``` | 配置项 | 说明 | 默认值 | |--------|------|--------| | server_ip | 服务端 IP 地址(支持 IPv4 和 IPv6) | ::1(本地回环) | | server_port | 服务端监听端口 | 9528 | **注意**: - 客户端配置的端口号必须与服务端启动时指定的端口号一致 - 客户端会自动根据 IP 地址格式识别 IPv4 或 IPv6 协议 - 服务端支持 IPv4/IPv6 双栈,可同时接受两种协议的连接 **常见配置示例:** - **本地测试(IPv6):** ```json { "server_ip": "::1", "server_port": 9528 } ``` - **本地测试(IPv4):** ```json { "server_ip": "127.0.0.1", "server_port": 9528 } ``` - **局域网部署(IPv6链路本地地址):** ```json { "server_ip": "fe80::1234:5678:abcd:ef01", "server_port": 9528 } ``` - **局域网部署(IPv4地址):** ```json { "server_ip": "192.168.1.100", "server_port": 9528 } ``` - **远程访问(IPv6全局单播地址):** ```json { "server_ip": "2001:0db8:85a3::8a2e:0370:7334", "server_port": 9528 } ``` --- ### 3. 运行客户端 ```bash # 运行客户端程序 ./UpdateToolClient ``` **客户端执行流程:** ``` 1. 读取 config.json 配置 ↓ 2. 扫描本地目录及所有子目录,计算每个文件的 MD5 值 ↓ 3. 创建 TCP 连接到服务端(自动识别 IPv4/IPv6) ↓ 4. 请求服务端文件列表(包含所有文件的路径、MD5、大小) ↓ 5. 比较文件差异: ├── 本地不存在 → 新增下载 ├── MD5不一致 → 更新覆盖 └── MD5一致 → 跳过 ↓ 6. 下载文件并保持目录结构 ↓ 7. 输出更新统计结果 ↓ 8. 按任意键退出 ``` #### 3.1 超时重连机制 客户端具备完善的网络异常处理和自动重连机制: **动态超时调整:** | 阶段 | 超时时间 | 说明 | |------|----------|------| | JSON 响应阶段 | 120 秒 | 请求文件列表、处理响应等操作 | | 文件数据接收阶段 | 15 秒 | 下载文件数据时的接收超时 | **重连策略:** ``` 连接失败或超时 → 等待 3 秒 → 重新连接 → 最多重试 3 次 ↓ 3 次重试均失败 → 输出错误信息 → 按任意键退出 ↓ 连接成功 → 继续未完成的更新任务 ``` **网络丢包检测:** - 文件数据接收阶段设置较短超时(15秒),可及时检测网络丢包 - 超时后自动关闭连接并触发重连机制 - 重连成功后从断点继续下载(基于已扫描的文件列表) **信号处理:** - 支持 `Ctrl+C` 强制退出,退出时会清理网络资源 - Windows 平台支持控制台关闭事件处理 - Linux 平台支持 `SIGINT` 和 `SIGTERM` 信号处理 **更新结果示例:** ``` ========== 更新完成 ========== 总文件数: 10 新增下载: 3 更新覆盖: 2 失败文件: 0 所有文件已成功更新! 按任意键退出... ``` --- ### 4. 文件同步规则 #### 4.1 更新判断逻辑 | 场景 | 本地状态 | 服务端状态 | 处理方式 | |------|----------|------------|----------| | 新增文件 | 不存在 | 存在 | 下载到本地 | | 更新文件 | 存在,MD5不同 | 存在 | 覆盖本地文件 | | 无需更新 | 存在,MD5相同 | 存在 | 跳过 | | 本地多余 | 存在 | 不存在 | **保留本地文件(不删除)** | #### 4.2 文件路径处理 - 路径分隔符统一使用 `/` - 文件相对路径从服务端/客户端根目录开始计算 - 目录结构自动创建,无需手动创建 **示例:** 服务端文件结构: ``` server_root/ ├── app.exe └── data/ └── config.txt ``` 更新后客户端文件结构: ``` client_root/ ├── UpdateToolClient.exe ├── config.json ├── app.exe # 新增或更新 └── data/ └── config.txt # 自动创建目录并下载 ``` --- ### 5. 单实例限制 - 客户端和服务端均采用 Windows 命名互斥锁实现单实例运行 - 如果检测到已有实例运行,会记录错误日志并退出 - 客户端互斥锁名称:`Global\UpdateTool_Client` - 服务端互斥锁名称:`Global\UpdateTool_Server` ## 通信协议 客户端与服务端采用长度前缀协议,所有消息(JSON 和文件数据)均使用此格式: ``` [8字节大端长度][内容] ``` ### 消息类型 | 类型 | 说明 | |------|------| | `get_file_list` | 客户端请求获取文件列表 | | `file_list` | 服务端返回文件列表 | | `download_file` | 客户端请求下载文件 | | `file_info` | 服务端返回文件信息(大文件分段传输时使用) | | `file_chunk` | 服务端返回文件块数据 | | `chunk_ack` | 客户端确认已接收文件块 | | `quit` | 客户端请求退出会话 | | `ok` | 服务端确认退出 | | `error` | 服务端返回错误信息 | ### 大文件分段传输 对于超过 256MB 的大文件,服务端采用分段发送方案: 1. 客户端请求下载文件后,服务端先返回 `file_info` 消息,包含文件大小和总块数 2. 服务端按顺序发送每个文件块(`file_chunk`),每块最大 256MB 3. 客户端接收每个块后发送 `chunk_ack` 确认 4. 服务端收到确认后才发送下一块 5. 文件数据使用长度前缀协议传输:`[8字节长度][文件数据]` **分段传输参数:** | 参数 | 值 | 说明 | |------|-----|------| | 块大小 | 256MB | 每个文件块的最大大小 | | 长度前缀 | 8字节 | 消息长度使用 uint64_t 大端序 | | 文件大小类型 | int64_t | 支持超过 4GB 的大文件 | ## 目录结构 ``` UpdateTool/ ├── CMakeLists.txt # 项目构建配置 ├── README.md # 项目说明文档 ├── 3rdparty/ # 第三方依赖库 ├── sdk/ # 基础SDK模块 │ ├── cfl/ # 基础工具库 │ └── log/ # 日志模块 ├── common/ # 公共组件 │ ├── CFileScan.h/cpp # 文件扫描类(多线程MD5计算) │ ├── CSingleInstance.h/cpp # 单实例检查类 │ ├── common.h # 协议常量定义和路径工具函数声明 │ └── common.cpp # 编码转换函数实现(宽字符串与UTF-8互转) ├── src/ │ ├── client/ # 客户端模块 │ │ ├── main.cpp # 客户端入口 │ │ ├── CClient.h/cpp # 客户端核心逻辑 │ │ ├── config.json # 客户端配置文件 │ │ └── CMakeLists.txt │ └── server/ # 服务端模块 │ ├── main.cpp # 服务端入口 │ ├── CServer.h/cpp # 服务端核心逻辑 │ └── CMakeLists.txt └── test/ # 单元测试 ``` ## 更新流程示例 ``` 服务端启动 → 扫描文件 → 监听端口 9528 │ ▼ 客户端启动 → 读取配置 → 扫描本地文件 → 连接服务端 │ │ ▼ ▼ 获取远程文件列表 ↓ 比较文件差异(MD5对比) ↓ ┌──────┴──────┬────────────┐ ▼ ▼ ▼ 新增文件 更新文件 无需更新 │ │ │ ▼ ▼ ▼ 下载文件 下载覆盖 跳过 │ │ └──────┬──────┘ ▼ 输出更新统计 按任意键退出 ``` ## 注意事项 1. 客户端和服务端必须在同一网络环境下,确保网络连通性(支持 IPv4 或 IPv6) 2. 服务端运行时,其所在目录即为文件服务根目录 3. 客户端会将文件下载到自身所在目录,保持与服务端相同的目录结构 4. 配置文件 `config.json` 必须与客户端程序在同一目录 5. 程序退出时会自动释放资源,无需手动清理