网络云盘系统---服务端/客户端搭建

  • 项目介绍和环境搭建

云盘系统的主要功能

自动将本地计算机上指定文件夹中需要备份的文件上传备份到服务器中,并且能够随时提供浏览器进行查看并且下载 其中下载过程支持断点续传功能 而且服务器也会对上传文件进行热点管理 将非热点文件进行压缩存储 节省磁盘空间 以下图示:

服务端实现思路
主要功能:
1.支持客户端文件上传功能
2.支持客户端文件备份列表查看功能
3.支持客户端文件下载功能(断点续传)
4.热点文件管理功能(对长时间无访问的文件进行压缩存储)

主要模块
1.数据管理模块(管理的备份的文件信息,以便于随时获取)
2.网络通信模块(实现与客户端的网络通信)
3.业务处理模块(上传,列表查看,下载(断点续传))
4.热点管理模块(对长时间无访问文件进行压缩存储)

客户端实现思路
主要功能:
1.指定文件夹中的文件检测(获取文件夹中有什么文件);能够自动检测客户机指定文件夹中的文件 并判断是否需要备份
2.判断指定的文件是否需要备份(新增,以及备份过但是又修改);将需要备份的文件逐个上传到服务器(上次上传后又修改过 但是已经间隔3秒钟没有被修改)
3.将需要备份的文件上传备份到服务器上
主要模块:
1.数据管理模块(备份的文件信息)
2.文件检测模块(监控指定的文件夹)
3.文件备份模块(上传需要备份的文件数据)


环境搭建

注意
为了提高开发效率,设计中使用了第三方库 
1.gcc 7.3.1
2.jsoncpp ---序列化反序列化准备
3.bundle数据压缩库 ---数据压缩与解压准备
4.httplib库 ---建立网络通信准备

  • 文件操作的实用工具

不管是客户端还是服务端 文件的传书备份都要涉及到文件的读写 包括数据管理信息的持久化也是如此 因此首先设计封装文件操作类 这个类封装完毕之后 则在任意模块中对文件进行操作时都要变的简单化

对文件进行操作
class{
   private:
         std::string _filename
   public:
         size_t FileSize();//1.获取文件大小
         time_t LastModTime();//获取文件最后一次修改时间
         time_t LastAccTime();//获取文件最后一次访问时间
         std::string FilenName();//获取文件路径名中的文件名称 /abc/test.txt -> text.txt
         bool SetContent(std::string &body);//向文件写入数据
         bool GetContent(std::string *body)
         bool GetPosLen(std::string *body,size_t pos,size_t len);//获取文件指定位置 指定长度的数据
         bool Exists();//判断文件是否存在
         bool  CreateDirectory();
         bool GetDirectory(std::vector<std::string>* arry);
         bool Compress(const std::string &packname);
         bool UnCompress(const std::string &filename);
};

本工具提供属性获得 读写操作 压缩与解压 目录操作等文件操作 以此提高开发效率 规范代码

  • 配置文件加载模块

使用文件配置加载一些程序的运行关键信息可以让程序运行更加灵活

配置信息设计
1.热点判断时间
2.文件下载的url前缀路径--用于表示客户端请求是一个下载请求
url:http://192.168.122.136:9090/path
当用户发来一个备份列表查看请求/listshow  我们如何判断这个不是一个listshow的文件下载请求
/download/test.txt     , /download/listshow
3.压缩包后缀名:   定义的 压缩包命名规则 就是在文件原名称之后加上后缀 ".lz"
4.上传文件存放路径:决定了文件上传之后实际存储在服务器的哪里
5.压缩包存放路径:决定了非热点文件压缩后存放的路径
6.服务端备份信息存放文件:服务端记录的备份文件信息的持久化存储
7.服务器的监听IP地址:当程序要运行在其他主机上 则不需要修改程序
8.服务器的监听端口

单例配置类设计
系统运行配置信息的单例类设计:
class Config{
     private:
         static std::mutex _mutex;  
          static Config* _instance;
         static Config* GetInstance();
          Config(){}
   private:
        int _hot_time;//热点判断时间
        int _server_port;//服务器监听端口
        std::string _download_prefix;//下载的url前缀路径
        std::string _packfile_suffix;//压缩包后缀名称
        std::string _back_dir;//备份文件存放目录
        std::string _pack_dir;// 压缩包存放目录
        std::string  _server_ip;//服务器IP地址
        std::string  _backup_file;//数据信息存放文件
public:
         int GetHotTime()
         int GetServerPort();
        std::string GetDownloadPrefix()
        std::string GetPackFileSuffix()
        std::string GetBackDir()
        std::string GetPackDir();
        std::string GetServerIp();
        std::string GetBackupFile();

}
  • 数据管理模块

数据管理设计
需要管理的数据有哪些 管理哪些数据 是因为后期要用到哪些数据
1.文件的实际存储路径:当客户端要下载文件时 则从这个文件中读取数据进行响应
2.文件压缩包存放路径名:如果这个文件是一个非热点文件会被压缩,则这个就是压缩包路径名称
如果客户端要下载文件 则需要先解压缩 然后读取解压后的文件数据
3.文件是否压缩的标志位:判断 文件是否已经被压缩了
4.文件大小
5.文件最后一次修改时间
6.文件最后一次访问时间
7.文件访问URL 中资源路径path:/download/a.txt
如何管理数据
1.用于数据信息访问:使用hash表在内存中管理数据 以url的path作为key值--查询速度快
2.持久化存储管理:使用json序列化将所有的数据信息保存在文件中

数据管理类的设计
管理服务端系统中会用到的数据
1.数据信息结构体:
typedef struct BackupInfo_t{
    bool pack_flag;//是否压缩标志
    size_t fszie;//文件大小
    time_t  atime;//最后一次访问时间
    time_t   mtime;//最后一次修改时间
    std::string real_path;//文件实际存储路径名称
    std::string pack_path;//压缩包存储路径名称
    std::string url_path;

}BackupInfo;


void NewBackupInfo(const std::string realpath,
BackupInfo* info)

class DataManager{
  private:
          std::string _backup_file;//持久化存储文件
          std::unordered_map<std::string,BackupInfo> _table;//内存中以hash表存储
           pthread_rwlock_t_rwlock;//读写锁--读共享 写互斥
public:
            DataManager();
            bool Storage();//每次数据新增或修改都要重新持久化存储 避免数据丢失
            bool InitLoad();//初始化加载 在每次系统重启都要加载以前的数据
            bool Insert(const BackupInfo &info);//新增
            bool Update(const BackupInfo &info);//修改
            bool GetOneByUrl(const std::string &url,BackupInfo *info)
            bool GetOneByRealpath(const std::string &path,BackupInfo* info)
            bool GetAll(std;:vector<BackupInfo>*arry);
            
}
  • 热点管理模块

    对服务器上备份的文件进行检测,哪些文件长时间没有被访问 则认为是非热点文件 则压缩存储 节省空间
    实现思路:
           遍历所有的文件 检测文件的最后一次访问时间 与当前时间进行相减得差值 这个差值如果大于所设定的非热点判断时间则认为是非热点文件,则进行压缩存放到压缩路径中 删除源文件

    如何遍历所有文件?有两种方案
    1.通过数据管理模块中遍历所有的备份文件信息
    2.遍历备份文件夹 获取所有文件进行属性获取 最终判断
    选择第二种 遍历文件夹 每次获取文件夹的最新数据进行判断 还可以解决数据信息缺失的问题


    1.遍历备份目录 获取所有文件路径名称
    2.逐个文件获取最后一次访问时间与当前系统时间进行比较判断
    3.对非热点文件进行压缩处理 删除源文件
    4.修改数据管理模块对应的文件信息(压缩标志-》true)

  • 服务器端业务处理模块

-业务处理实现思路:
将网络通信和业务处理进行了合并(网络通信通过hhtplib库完成)
1.搭建网络通信服务器:借助httplib完成
2.业务请求处理
       1.文件上传请求:备份客户端上传的文件,响应上传成功
       2.文件列表请求:客户端浏览器请求一个备份文件的展示页面 响应页面
       3. 文件下载请求:通过展示页面 点击下载 响应客户端要下载的文件数据

网络通信接口
网络通信接口设计:约定好,客户端发送什么样的请求 我们给与什么样的响应
请求:文件上传 展示页面 文件下载
接口设计:
1.文件上传
2.展示页面 
3.文件下载

文件上传请求:
当服务器收到了一个POST方法的/upload请求,我们则认为这是一个文件上传请求解析请求 得到文件数据 将数据写到文件中
HTTP/1.1 200 ok //响应

展示页面的请求

展示页面的html
 GET /listshow HTTP/1.1                    /展示页面的请求

.......

HTTP/1.1 200 OK'
文件下载请求

GET /download/test.tx HTTP /1.1              ///文件下载请求
..........
HTTP/1.1 200 OK                                      ///
Content-Length:文件长度

正文就是文件数据

断点续传


功能:当文件下载过程中 因为某种异常而中断 如果再次进行从头下载 效率较低 因为需要将之前已经传输过的数据再次传输一遍 因此断点续传就是从上次下载断开的位置 重新下载即可 之前已经传输过的数据将不再需要重新传输
目的:提高文件重新传输效率
实现思想:
     客户端在下载文件的时候 要每次接收到数据写入文件后记录自己当前下载的数据量
当异常下载中断时 下次断点续传的时候 将要重新下载的数据区间(下载起始位置,结束位置)发送给服务器 服务器收到后 ,仅仅回传客户端需要的区间数据即可
需要考虑的问题:如果上次下载文件之后 这个文件在服务器上被修改了 则这时候将不能重新断点续传 而是应该重新进行文件下载操作

在http协议中断点续传的实现:
主要关键点:
1.在于能够告诉服务器下载区间范围
2.服务器上要能够检测上一次下载之后这个文件是否被修改过
实现:
文件下载:
GET /download/test.txt HTTP/1.1
....
HTTP/1.1 200 ok
Accept-Ranges:bytes 告诉客户端服务器支持断点续传功能
ETag:“sdjasdpajsod-文件唯一标识”客户端收到响应会保存这个消息
....
文件数据作为正文
断点续传:
GET /download/test.txt HTTP/1.1
if-Range:"服务端在下载时响应的etag字段" 用于服务端判断这个文件与原先下载的文件是否一致 
Range:bytes 100-10000  这个字段用于高速服务区客户端需要的数据区间范围
响应:
HTTP/1.1 206 Partial Content
Etag:"shdoaisdhi"
Content-Range:bytes 100-10000/文件大小
正文就是对应的区间数据
Range:bytes start-end
              bytes 100-200
              bytes 100 - //这个表示的是从第100字节开始到文件末尾

业务处理类的设计
三个接口


搭建服务器所需的信息

  • 客户端业务处理模块

功能回顾与数据信息设计
要实现的功能:自动对指定文件夹中的文件进行备份
进行的模块划分:
     数据管理模块:管理备份的文件信息
     目录遍历模块:获取指定文件夹中的所有文件路径名
      文件备份模块:将需要备份的文件上传备份到服务器
客户端要备份文件,什么文件需要备份,都是通过数据管理判断的
数据管理模块:要管理的数据设计
    数据管理模块:其中的信息用于判断一个文件是否需要重新备份
     1.文件是否是新增的
     2. 不是新增的 则上次备份后有没有被修改过
管理的数据:文件的路径名,文件的唯一标识 
当前的客户端的程序开发 是在window下的  实用性没人用Linux日常使用
使用的工具是vs2017以上版本(需要支持c++17)
数据管理模块的实现思想:
1. 内存存储:高访问效率--使用的是hash表--unordered_map
2.持久化存储:文件存储
文件存储涉及到数据序列化:因为在vs中安装jsoncpp较为麻烦 ,直接自定义序列化格式 
key val:key是文件路径名,val是文件唯一标识
key val\nkey val\n
文件的唯一标识:用于判断上次文件上传后有没有被修改过

以上就是网络云盘系统的详细介绍

如果需要了解源码请点击连接cloud_backup/src · gggalaxy/2023_learning log_Mac - 码云 - 开源中国 (gitee.com)

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值