我们这里由于网络通信模块借助httplib库来完成,因此两个模块合并到一起完成,不熟悉httplib库的老铁可以再看看我之前的文章
我们这里主要需要实现的功能有两个:1. 搭建网络通信服务器。2.服务器针对客户端的请求进行业务处理
前者我们借助httplib实现,因此我们本模块的核心重点放到业务请求处理方向
我们的业务请求处理主要是需要处理下面三个核心请求
1. 文件上传请求:备份客户端上传的文件,并进行响应
2. 文件列表请求:当客户浏览器申请文件列表或者默认资源路径请求,我们都响应备份文件信息列表,进行页面展示
3. 文件下载请求: 通过展示页面,点击下载,响应客户端要下载的数据
因此结合我们之前httplib库的使用案例,我们接口设计如下
- #ifndef _MY_SER_
- #define _MY_SER_
-
- #include "config.hpp"
- #include "data_manager.hpp"
- #include "hot_manager.hpp"
- #include "util.hpp"
- #include "httplib.h"
-
- namespace mjw_cloud
- {
- class Server
- {
- public:
- Server()
- {}
- bool Run()//服务器启动,并将响应的客户端请求和对应处理函数捆绑
- {}
- private:
- //注意回调函数都需要用static修饰成为静态成员函数,因为httplib库中函数要求的参数只有两个
- //类成员函数如果不用static修饰,那么会多出来一个this指针参数,httplib回调就会出错
-
- //上传文件
- static void UpLoad(const httplib::Request& req,httplib::Response& res);
- //备份文件信息展示
- static void ListShow(const httplib::Request& req,httplib::Response& res);
- //备份文件下载
- static void Dwonload(const httplib::Request& req,httplib::Response& res);
-
- private:
- int _server_port; // 端口号
- std::string _server_ip; // 服务器ip
- std::string _download_prefix; // 下载路径前缀
- httplib::Server _server; // httplib库搭建服务器
- };
- }
-
- #endif
网络通信接口设计,客户端和服务端是约定好的,客户端发送什么样的请求,服务端回复对应的响应

![]()

如上图,是我们服务端上传文件时所用html页面,其对应核心报文如下所示

观察其报文我们发现,主要内容里面不全是核心内容(也就是上传的文件),因此拿到报文后需要解析请求,然后拿到文件数据(httplib库完成),然后我们在将数据写入到文件存储起来,然后向客户端响应报文(主要是响应上传成功,因此返回状态码200即可)

代码实现如下所示

当客户浏览器申请文件列表或者默认资源路径请求,我们都响应备份文件信息列表,进行页面展示

客户浏览器申请文件列表请求的报文如上所示

我们服务端需要回复的报文如上所示,文本信息中的内容是需要我们根据备份文件信息进行填充,其他主要内容不变
代码实现如下


上面时客户端下载文件是发送的报文,下面是服务端响应时需要构建的报文

其中Etags以及Accopt_Ranges见到的可能比较少
Etags主要是作为文件唯一标识,当我们第一次发送文件时客户端会收到这个消息,当客户端第二次下载,会将这个标识发送给服务器,服务器会根据这个标识判断,这个资源如果没有被修改,则直接使用原先数据的缓存,无需从新下载。
这里我们选择用"文件名-文件大小-文件最后一次修改时间"来组成这个唯一标识
Accept-Ranges主要是断点续传会用到,后面会再说
代码实现

业务处理模块基本完成,但是备份文件下载还有断点重传的重要功能没有讲解,我们将放到后续进行讲解