项目实现目标
项目设计
服务端负责功能
客户端负责功能
能够自动检测客户机指定文件夹中的文件,并判断是否需要备份。
将需要备份的文件逐个上传到服务器。
项目环境
服务器: centos7(以上)/ vim、g++(7.3以上)、gdb、makefile
客户端: Windows10/ vs2017(以上)
使用到的库
Jsoncpp 库:
jsoncpp 库用于实现 json 格式的序列化和反序列化,完成将多个数据对象组织成为 json 格式字符串,以及将 json 格式字符串解析得到多个数据对象的功能。
Bundle 库:
Httplib 库:
C++17 filesystem库:
使用该库实现服务端和客户端的文件操作工具类实现( util.hpp ), 实现文件目录的创建, 检索文件是否存在, 获取不带路径的纯文件名, 浏览遍历指定目录下文件, 删除文件等操作。
模块实现
服务端数据管理模块
上传的文件,最终是用户在浏览器上进行查看并下载的,而浏览器界面上需要能够展示客户端曾经备份过的文件: 原文件名,文件大小,文件备份时间
服务端热点管理模块:
服务端网络通信模块与业务处理模块:
上传:上传请求业务处理通过服务器接收到的 http 请求正文实现, 通过 MutipartFormData 中的区域标识符字段name是否为 "file" 判断上传的是否为文件, 再通过 filename 文件名字段获取备份文件名, content字段获取备份文件的内容, 通过 File_util 中的 write 接口实现备份, 添加备份信息, 成功返回 200OK 响应状态码.
查看: 查看请求业务处理通过遍历获取备份文件夹下所有备份文件的文件信息, 将文件信息组织渲染成html页面, 这里简单学了最基本的前端知识来写了个页面, 将文件名作为 /download/filename 超链接, 客户端浏览器点击该文件名即向服务点发送 /download/filename 下载文件请求. 将写好的html 页面作为响应正文返回.
下载: 下载请求业务具有断点续传功能, 断点续传: 当下载一个文件的时候,下载到中途,因为网络或者其他原因,导致下载中断, 如果第二次后边重新下载所有文件数据,效率就比较低,因为实际上之前传输的数据是不需要重新传输的如果这次下载只是从上一次断开的位置重新下载,就可以提升很高的下载效率.
客户端数据管理模块:
客户端的数据处理模块不需要管理太多的文件数据, 只需要记录 "文件名= etag" 即可, 所以不需要json库的将信息序列化存储也就不需要按序列化这两个接口了, 当然客户端也不需要压缩解压缩接口. File_util 的代码是linux, windows都可以复用的, 所以获取文件信息, 创建备份文件目录, 创建备份文件信息文件等直接复用 util.hpp 代码即可. 客户端的数据管理模块也是对文件信息的增删改查,
增: 将文件放入上传备份的文件夹中, 则增加放入的文件的文件信息.
删: 和服务端一样, 作为拓展模块, 一般不需要调用删除.
改: 在判断文件是否需要上传时, 若此时文件信息和之前保存发文件信息不同了则上传, 同时更新文件存储信息.
查: 通过查询保存的文件信息etag与当前时刻的文件etag比较时使用.
客户端目录检查模块:
客户端的目录检索模块复用服务端 util.hpp 代码, 实现相同的功能.
客户端网络通信模块:
通过不断遍历备份文件夹中的文件, 判断其是否需要上传, 判断条件: 1. 该文件没有存储文件信息, 则说明该文件是刚放入备份文件夹的, 还没有备份上传, 需要备份. 2. 若存在备份文件信息, 则比较当前的etag与之前保存的etag比较, 若不相同则需要上传( 若最后一次访问时间与当前时间比较, 大于指定时间则认为用户已对文件修改完成, 可以上传, 否则认为用户还在修改, 先不上传, 等下次循环再判断时间是否大于, 大于则认为修改完成, 可以上传.)
需要上传则使用 httplib 搭建客户端, 通过对库中MultipartFormData 设置区域标识字段 name="file" , 文件名filename="xxx" , File_util中 Read(xxx) 读取该文件的内容到content正文中, 再将MultipartFormData结构体通过 httplib::Post()接口即可实现上传.