当前位置: 首页 > news >正文

个人博客网站如何做SEO重庆公司章程在哪里下载

个人博客网站如何做SEO,重庆公司章程在哪里下载,宁乡网页设计,wordpress 提示插件项目总结 整体回顾逐步实现utill.hppconfig.hppdata.hpphot.hppservice.hpp 代码 整体回顾 服务端的目标是#xff1a; 对客户端的请求进行处理管理客户端上传的文件 于客户端进行数据交换#xff0c;我们需要引入网络#xff0c;所以我们引入第三方库----httplib.h库 对客户端的请求进行处理管理客户端上传的文件 于客户端进行数据交换我们需要引入网络所以我们引入第三方库----httplib.h库搭建服务端。在进行网络通讯时数据需要被系列化和反序列化否则有数据丢失的风险还需引入json库 在管理文件时需要进行热点管理把非热点文件进行压缩也需要引入第三方库 ----bundle.h,对文件进行压缩。 因此我们可以给服务端的各种功能实现划分模块逐步实现服务端的整体功能。 要对上传的文件的文件进行管理我们需要---- 文件管理模块 同时在将文件管理后我们需要对其进行更一步的热带管理模块热点管理的实现是在文件管理模块的实现之上的。 在本地测试好了上述两个模块后我们可以进行网络通讯了。 需要一个网络通讯模块通过其搭建我们的服务端 能进行网络通讯后还需要一个业务处理模块处理客户端发送过来的请求并予以响应。 逐步实现 先创建一个库util.hpp工具库文件 里面有我们自己实现的几个util工具类。 工欲善其事必先利其器。 utill.hpp class FileUtil{} 创建一个FileUtil 类文件工具类对系统的文件接口进行封装便于我们对文件快捷操作提供对文件的增删查改 class FileUtil{ private:std::string _name; public:FileUtil(const std::string name);size_t FileSize();// 文件大小time_t LastATime(); // 最后一次查看文件时间time_t LastMTime(); // 最后一次修改文件的时间std::string FileName(); //文件名字bool GetPosLen(std::string *content, size_t pos, size_t len); //获取文件流pos 后len个长度的数据bool GetContent(std::string *content); //获取文件内容bool SetContent(std::strint *content); //写入文件bool Compress(const std::string packname); //压缩文件bool UnCompress(const std::string filename); //解压文件bool Exists(); //判断文件是否存在bool CreateDirectory(); //创建一个目录bool ScanDirectory(std::vectorstd::string *arry); //查看目录下的文件内容}FileUtile 工具提供了对文件的增删查改的功能也提供了对目录的查看功能和创建目录的功能 其中对文件压缩解压缩时我们需要借用bundle.h库的函数如何使用bundle库里的函数在GitHub上有完整的教程。 同时我们在查看目录时需要借助filesystem库的使用但是只有在c17以上的版本才支持filesystem 注意 在Windows下我们要选择了vs2017以上的版本在Linux下我们需要将gcc进行升级7.3版本 class jsonutil jsonutil类为网络通讯时的数据提供系列化和反序列化的功能当然需要引入json库 至此我们的基础工具已经完善可以以此为基础更一步完善服务端的功能。 config.hpp 项目配置信息的管理启动项目时会自动从 .conf文件加载项目的配置信息。需要修改部分内容时不需要在代码上修改只需要修改配置文件然后重启服务器即可。 采用json 格式将配置信息存放在Cloud.conf中当启动服务器时由服务器从.conf文件中读取关键数据。 Cloud.conf 文件 { “hot_time” : 30, “server_port” : 9090, “server_ip” : “1.1.1.1”, “url_prefix” : “/download/”, “arc_suffix” : “.lz”, “pack_dir” : “./packdir/”, “back_dir” : “./backdir/”, “manager_file” : “./back.dat” } #define CONFIG_FILE ./cloud.conf class Config{ private:time_t _hot_time;int _server_port;std::string _server_ip;std::string _url_prefix;std::string _arc_suffix;std::string _pack_dir;std::string _back_dir;std::string _manager_file;//备份信息的配置管理 private:static std::mutex _mutex;static Config *_instance;Config(); public:bool ReadConfig(const std::string filename);int GetHotTime();int GetServerPort();std::string GetServerIp();std::string GetURLPrefix();std::string GetArcSuffix();std::string GetPackDir();std::string GetBackDir();std::string GetManagerFile(); public:static Config *GetInstance(); }; 且在实现配置信息类时我们采取单例模式。 data.hpp data.hpp是数据管理模块的主要部分。 要管理文件数据就得先对文件的信息进行组织。 struct BackupInfo{} typedef struct BackupInfo{bool pack_flag; // 文件是否被压缩的标识time_t atime; // 最后一次查看时间time_t mtime; // 最后一次修改时间size_t fsize; //文件大小std::string real_path; // 文件在服务器上的真实存储路径std::string url; // 客户端访问文件时的请求urlstd::string packpath; // 压缩包存储路径bool FillBackupInfo(const std::string realpath){}}BackupInfo;有了这些数据后我们能准确的描述一个文件并可以很好的进行管理。 上传的文件信息都以BackuoInfo的模式以json的格式存储在backup_file中当程序启动时需要去文件加载数据到内存。同时在新上传文件后我们也需要将文件数据永久化存储到backup_file中。也需要支持对已经被管理的文件信息的增删查改我们暂时不支持对信息的删除现在只涉及最基础的功能实现更多功能在已经构建好整个框架后会进一步实现。 整个数据管理模块也为让上层迅速查找文件的备份信息 class DateManager{} class DataManager{ private:FileUtil _backup_file;pthread_rwlock_t _rwlock; // 读写锁std::unordered_mapstd::string, BackupInfo _table; public:DataManager();bool InitLoad();//初始化程序运行时从文件读取数据bool Storage(); //每次有信息改变则需要持久化存储一次bool Insert(const std::string key, const BackupInfo val);bool Update(const std::string key, const BackupInfo val);bool GetOneByURL(const std::string key, BackupInfo *info);bool GetOneByRealPath(const std::string key, BackupInfo *info);bool GetAll(std::vectorBackupInfo *arry); };其具体实现内容在项目日志时已经说过在此不再重复。 注意 我们是对 _table 加上了rwlock 读写锁因为这里的并发访问场景更多的是读读读写场景能提高服务器运行速度。 同时加锁的原因是 在httplib库中使用了线程池的技术当服务端accept一个客户端后会另起一个线程在服务端处理请求所以 _table属于临界资源需要加锁保护。 我们的Storage()是覆盖式存储是将 内存中 _table里的所有数据进行反序列将 backup_file里的内容进行覆盖。 hot.hpp 热点管理模块就压要简单一点很大一部分工作在数据管理模块已经完成。 循环遍历目录下的所有文件然后通过文件最后一次修改时间来判断该文件是否为热点文件然后压缩至指定目录即可。 extern cloud::DataManager *_data; class HotManager{ private:std::string _back_dir;std::string _pack_dir;std::string _pack_suffix;time_t _hot_time; public: HotManager();bool HotJudge(const std::string file);bool RunModule(); };因为数据管理是要在多个模块中访问的因此将其作为全局数据定义。 service.hpp 云备份项目中 业务处理模块是针对客户端的业务请求进行处理并最终给与响应。而整个过程中包含以下要实现 的功能 借助网络通信模块httplib库搭建http服务器与客户端进行网络通信针对收到的请求进行对应的业务处理并进行响应文件上传列表查看文件下载包含断点续传 响应给客户端的 rsp在之前的项目日志里也有描述。 class Service{ private:int _server_port;std::string _server_ip;std::string _url_prefix;httplib::Server _srv; private:static void Upload(const httplib::Request req, httplib::Response rsp);static void List(const httplib::Request req, httplib::Response rsp);static void Download(const httplib::Request req,httplib::Response rsp); public:Service();bool RunModule(); }注意 业务处理的回调函数没有传入参数的地方大概是因为回调函数的模板被固定化了因此无法直接访问外部的数据管理模块数据因此将数据管理模块的对象定义为全局数据,在这里声明一下就可以在任意位置访问了,且回调函数必须为静态函数类内函数成员变量会隐藏一个this指针。 文件上传函数和文件列表查看函数都按照思路来写。 文件下载函数有部分事项需要注意 1 . 服务端要判断是否需要进行断点重传判断条件 有If-Range字段且这个字段的值与请求文件的最新etag一致则符合断点续传 也就是说需要在客户端请求里有If-Range字段且在这段时间内文件的数据内容没有被修改过。 这是Download 函数正常的响应rsp HTTP/1.1 200 OK Content-Length: 100000 ETags: filename-size-mtime一个能够唯一标识文件的数据 Accept-Ranges: bytesAccept-Ranges报头 服务器使用 HTTP 响应头 Accept-Ranges 标识自身支持范围请求 (partial requests)。字段的具体值用于定义范围请求的单位。 当浏览器发现Accept-Ranges头时可以尝试继续中断了的下载而不是重新开始。 这是Download执行断点续传的rsp HTTP/1.1 206 Partial Content Content-Length: Content-Range: bytes 89-999/100000 Content-Type: application/octet-stream ETag: inode-size-mtime一个能够唯一标识文件的数据 Accept-Ranges: byteshttplib内部实现了对于区间请求也就是断点续传请求的处理 只需要我们用户将文件所有数据读取到rsp.body中它内部会自动根据请求 区间从body中取出指定区间数据进行响应并且会自动填充rsp内容。 代码 代码里边会有博主的一些思考和理解各位大佬见笑了 util.hpp #pragma once#include iostream #include string #include fstream #include vector #include sys/types.h #include sys/stat.h #include unistd.h #include memory #include experimental/filesystem #include bundle.h #include jsoncpp/json/json.hnamespace Cloud {namespace fs std::experimental::filesystem;class FileUtil{private:std::string _Filename;public:FileUtil(std::string fname) : _Filename(fname){}int64_t Filesize() // 提取文件大小{struct stat st;if (stat(_Filename.c_str(), st) 0){std::cerr get Filesize fail std::endl;return -1;}return st.st_size;}std::string Filename() // 提取文件名{// /a/b/文件名size_t pos _Filename.find_last_of(/);if (pos std::string::npos){return _Filename;}return _Filename.substr(pos 1);}time_t LastMtime() // 提取文件最后一次的修改时间文件内容{struct stat st;if (stat(_Filename.c_str(), st) 0){std::cerr get File LastMtime fail\n std::endl;return -1;}return st.st_mtime;}time_t LastAtime() // 提取文件最后一次的访问时间{struct stat st;if (stat(_Filename.c_str(), st) 0){std::cerr get File LastAtime fail\n std::endl;return -1;}return st.st_atime;}time_t LastCtime() // 提取文件最后一次的修改时间文件内容 || 文件属性{struct stat st;if (stat(_Filename.c_str(), st) 0){std::cerr get File LastCtime fail\n std::endl;return -1;}return st.st_ctime;}bool Remove(){remove(_Filename.c_str());return true;}bool GetPosLen(std::string body, size_t pos, size_t len){size_t fsize this-Filesize();if (pos len fsize){std::cout get file len is error\n;return false;}std::ifstream ifs;ifs.open(_Filename, std::ios::binary);if (ifs.is_open() false){std::cout read open file failed!\n;return false;}ifs.seekg(pos, std::ios::beg);body.resize(len);ifs.read(body[0], len);if (ifs.good() false){std::cout get file content failed\n;ifs.close();return false;}ifs.close();return true;}bool GetContent(std::string body){size_t fsize this-Filesize();return GetPosLen(body, 0, fsize);}bool SetContent(const std::string body){std::ofstream ofs;ofs.open(_Filename, std::ios::binary);if (ofs.is_open() false){std::cout write open file failed!\n;return false;}ofs.write(body[0], body.size());if (ofs.good() false){std::cout write file content failed!\n;ofs.close();return false;}ofs.close();return true;}bool Compress(const std::string packname){// 1. 获取源文件数据std::string body;if (this-GetContent(body) false){std::cout compress get file content failed!\n;return false;}// 2. 对数据进行压缩std::string packed bundle::pack(bundle::LZIP, body);// 3. 将压缩的数据存储到压缩包文件中FileUtil fu(packname);if (fu.SetContent(packed) false){std::cout compress write packed data failed!\n;return false;}return true;}bool UnCompress(const std::string filename){// 将当前压缩包数据读取出来std::string body;if (this-GetContent(body) false){std::cout uncompress get file content failed!\n;return false;}// 对压缩的数据进行解压缩std::string unpacked bundle::unpack(body);// 将解压缩的数据写入到新文件FileUtil fu(filename);if (fu.SetContent(unpacked) false){std::cout uncompress write packed data failed!\n;return false;}return true;}bool Exists(){return fs::exists(_Filename);}bool CreateDirectory(){if (this-Exists())return true;return fs::create_directories(_Filename);}bool ScanDirectory(std::vectorstd::string arry){CreateDirectory();for (auto p : fs::directory_iterator(_Filename)){if (fs::is_directory(p) true){continue;}// relative_path 带有路径的文件名arry.push_back(fs::path(p).relative_path().string());}return true;}};class jsonutil{public:static bool Serialize(const Json::Value root, std::string str) // 序列化{Json::StreamWriterBuilder swb;std::unique_ptrJson::StreamWriter sw(swb.newStreamWriter());std::stringstream ss;if (sw-write(root, ss) ! 0){std::cout json write failed!\n;return false;}str ss.str();return true;}static bool UnSerialize(const std::string str, Json::Value root) // 反序列化{Json::CharReaderBuilder crb;std::unique_ptrJson::CharReader cr(crb.newCharReader());std::string err;bool ret cr-parse(str.c_str(), str.c_str() str.size(), root, err);if (ret false){std::cout parse error: err std::endl;return false;}return true;}}; } data.hpp #pragma once#include unordered_map #include pthread.h #include iostream #include util.hpp #include config.hpp #include string #include stdio.h// 服务端要管理文件数据需要 先描述在组织 构建一个文件属性结构体通过这个结构体来管理所有的文件 namespace Cloud {typedef struct BackupInfo{bool pack_flag; // 文件是否被压缩的标识time_t atime; // 最后一次查看时间time_t mtime; // 最后一次修改时间size_t fsize;std::string real_path; // 文件在服务器上的真实存储路径std::string url; // 客户端访问文件时的请求urlstd::string packpath; // 压缩包存储路径bool FillBackupInfo(const std::string realpath){FileUtil ft(realpath);if (ft.Exists() false){std::cerr fill backupinfo:file not exists std::endl;return false;}Config *cf Config::Getinstance();pack_flag false;atime ft.LastAtime();mtime ft.LastMtime();fsize ft.Filesize();real_path realpath;// ./backdir/a.txt - /download/a.txturl cf-GetDownloadPrefix() ft.Filename();// ./packdir/a.txt - ./packdir/a.txt.lzpackpath cf-GetPackDir() ft.Filename() cf-GetPackFileSuffix();return true;}} BackupInfo;class DateManager{private:std::string _backup_file; // 文件的信息都会以json的格式存放在 一个backup文件里pthread_rwlock_t _rwlock; // 对backup文件会存在并发访问的问题 ------- ????????????????? 不懂为什么有锁std::unordered_mapstd::string, BackupInfo _table; // 以hash结构url 为key BackupInfo 为val 查找迅速public:// 从文件中读取数据进行初始化 对文件增删查改 对文件的永久化储存DateManager(){// printf(准备Datemanager初始化\n);_backup_file Config::Getinstance()-GetBackupFile();pthread_rwlock_init(_rwlock, nullptr);initload();// std::cout初始化成功std::endl;}bool insert(const BackupInfo bf){// ? 我自己的思路 --------- 传入一个 filename 然后在insert函数中自己填充BackupInfo数据 在插入进_table中 ----》 可以减少上层的工作量 我觉得pthread_rwlock_wrlock(_rwlock);std::string url bf.url;_table[url] bf;pthread_rwlock_unlock(_rwlock);Storage();return true;}bool update(const BackupInfo bf){// 问题同 insert函数pthread_rwlock_wrlock(_rwlock);std::string url bf.url;_table[url] bf;pthread_rwlock_unlock(_rwlock);Storage();return true;}bool GetOneByURL(const std::string url, BackupInfo *info){pthread_rwlock_rdlock(_rwlock);auto it _table.find(url);if (it ! _table.end()){*info it-second;}else{pthread_rwlock_unlock(_rwlock);return false;}pthread_rwlock_unlock(_rwlock);return true;}bool GetOneByRealpath(const std::string realpath, BackupInfo *info){// std::cout准备拿锁std::endl;pthread_rwlock_rdlock(_rwlock);// std::cout拿到锁了std::endl;std::unordered_mapstd::string, BackupInfo::iterator it _table.begin();// std::cout找到初始位置了std::endl;for (; it ! _table.end(); it){if (it-second.real_path realpath){*info it-second;pthread_rwlock_unlock(_rwlock);return true;}}pthread_rwlock_unlock(_rwlock);return false;}void GetAll(std::vectorBackupInfo *arry){pthread_rwlock_wrlock(_rwlock);for (auto it _table.begin(); it ! _table.end(); it){arry-push_back(it-second);}pthread_rwlock_unlock(_rwlock);}bool Storage() // 每次有信息改变则需要持久化存储一次{// 1. 获取所有数据std::vectorBackupInfo arry;this-GetAll(arry);// 2. 添加到Json::ValueJson::Value root;for (int i 0; i arry.size(); i){Json::Value item;item[pack_flag] arry[i].pack_flag;item[fsize] (Json::Int64)arry[i].fsize;item[atime] (Json::Int64)arry[i].atime;item[mtime] (Json::Int64)arry[i].mtime;item[real_path] arry[i].real_path;item[packpath] arry[i].packpath;item[url] arry[i].url;root.append(item); // 添加数组元素}// 3. 对Json::Value序列化std::string body;jsonutil::Serialize(root, body);// 4. 写文件FileUtil fu(_backup_file);fu.SetContent(body);return true;}bool initload() 初始化程序运行时从文件读取数据 ------- 为什么不从备份目录中提取数据 --- 备份目录下的文件会被压缩至压缩目录{// 1. 从文件中读取数据// printf(准备读数据\n);FileUtil ft(_backup_file);// printf(读数据成功\n);if (ft.Exists() false) // 如果文件不存在说明还没有数据存入数据文件也就是还没有创建数据文件{// printf(文件不存在\n);return true;}std::string str;// printf(准备获得文\n);ft.GetContent(str);// printf(获得文成功\n);// 2. 将数据反序列化// printf(准备序列化\n);Json::Value root;jsonutil::UnSerialize(str, root);// printf(反序列化成功\n);// 3. 将数据插入_table// printf(准备插入数据:%d\n,root.size());for (int i 0; i root.size(); i){// std::cout开始插入数据std::endl;BackupInfo info;info.pack_flag root[i][pack_flag].asBool();info.fsize root[i][fsize].asInt64();info.atime root[i][atime].asInt64();info.mtime root[i][mtime].asInt64();info.packpath root[i][packpath].asString();info.real_path root[i][real_path].asString();info.url root[i][url].asString();// std::cout插入:info.urlstd::endl;insert(info);}return true;}~DateManager(){pthread_rwlock_destroy(_rwlock);}};} hot.hpp #pragma once#include unistd.h #include data.hpp #include iostreamextern Cloud::DateManager *_data;namespace Cloud {class HotManager{private:std::string _back_dir;std::string _pack_dir;std::string _pack_suffix;int _hot_time;public:HotManager(){Config *cng Config::Getinstance();_back_dir cng-GetBackDir();_pack_dir cng-GetPackDir();_pack_suffix cng-GetPackFileSuffix();_hot_time cng-GetHotTime();FileUtil tmp1(_back_dir);FileUtil tmp2(_pack_dir);tmp1.CreateDirectory();tmp2.CreateDirectory();}bool HotJudge(const std::string filename) // 返回true 说明为非热点文件{FileUtil fu(filename);time_t curtime time(NULL);if (curtime - fu.LastAtime() _hot_time)return true;return false;}void RunModel() // 不断循环检测 back_dir 目录下的文件 进行热点管理{while (true){// 1. 遍历备份目录获取所有文件名FileUtil fu(_back_dir);std::vectorstd::string arry;fu.ScanDirectory(arry);// std::cout准备判断是否为热点文件std::endl;//,没什么问题// 2. 判断文件是否为热点文件// std::coutarry.size()std::endl;for (const auto it : arry){// std::cout开始遍历判断是否为热点文件std::endl;// std::coutitstd::endl;if (HotJudge(it) false){// std::cout不是热点文件std::endl;continue;}// 获取文件的备份信息BackupInfo info;// std::cout准备执行HOT里的GetonebyRealpathstd::endl;if (_data-GetOneByRealpath(it, info) false){// std::cout准备执行fillBackupInfostd::endl;info.FillBackupInfo(it);}// 3. 对非热点文件进行压缩FileUtil tmp(it);tmp.Compress(info.packpath);// 4. 删除源文件修改备份信息tmp.Remove();info.pack_flag true;_data-update(info);}// std::cout准备进入睡眠std::endl;usleep(1000);}}}; } service.hpp #pragma once#include errno.h #include string #include data.hpp #include hot.hpp #include httplib.h// 服务端构建服务器 为客户端提供 上传文件upload 下载文件(get) 文件列表查看()三个req // 并对客户端 进行响应 响应上传成功 响应下载的文件数据 响应一个展示文件备份列表的前端页面extern Cloud::DateManager *_data;namespace Cloud {std::string totimestring(const time_t tm){struct tm *tmp localtime(tm);char buffer[1024];snprintf(buffer, sizeof(buffer), %d-%d-%d %d:%d:%d, tmp-tm_year 1900, tmp-tm_mon 1, tmp-tm_yday,tmp-tm_hour, tmp-tm_min, tmp-tm_sec);return buffer;}class Service{private:std::string _server_ip;uint16_t _server_port;std::string _download_prefix; // 我自己粗略认为这是充当客户端请求下载文件时url中的前一部分httplib::Server _server;public:Service(){printf(Service 开始初始化\n);Config *config Config::Getinstance();_server_ip config-GetServerIp();_server_port config-GetServerPort();_download_prefix config-GetDownloadPrefix();printf(ser 初始化成功\n);}void RunModule(){printf(Server RunModulem 开始\n);_server.Post(/Upload, Upload);_server.Get(/, Showlist);_server.Get(/Showlist, Showlist);// 下载文件需要匹配具体的文件名需要借用正则表达式_server.Get(_download_prefix .*, Download);printf(server 开始listen\n);std::cout _server_ip :: _server_port std::endl;if (_server.listen(_server_ip.c_str(), _server_port) false){std::cout listen error errno std::strerror(errno) std::endl;}}private:static void Upload(const httplib::Request req, httplib::Response rsp) // 上传文件数据{// 1. 对req进行反序列化(httplib已经帮我们做过了) 提取数据printf(收到一个upload请求\n);auto ret req.has_file(file); // 判断req请求中是否包含 上传的文件字段if (ret false){rsp.status 400;return;}// 2. 拿到文件名拿到文件数据const auto file req.get_file_value(file);std::string filename file.filename;std::string filecontent file.content;// 3. 将其保存至 backdir目录下 ,std::string backdir Config::Getinstance()-GetBackDir();std::cout backfilename: backdir filename std::endl;FileUtil fu(backdir filename);fu.SetContent(filecontent);// 修该组织文件备份的管理信息BackupInfo info;info.FillBackupInfo(backdir filename);_data-insert(info);// 4. 同时填充rsprsp.status 200;printf(upload 完成\n);return;}// 唯一标识符 filename-filesize-lastmtimestatic std::string GetETag(const BackupInfo info){FileUtil fu(info.real_path);std::string etag fu.Filename();etag -;etag std::to_string(info.fsize);etag -;etag std::to_string(info.mtime);return etag;}// static void Download(const httplib::Request req, httplib::Response rsp)// {// printf(收到一个Download请求\n);// // 1. 从req中提取url通过url找到 获取文件备份信息// BackupInfo info;// _data-GetOneByURL(req.path, info);// std::cout req.path std::endl;// std::cout info.packpath : info.real_path std::endl;// std::cout info.pack_flag std::endl;// printf(提取到info信息\n);// // 3. 判断是否被压缩// if (info.pack_flag true)// {// printf(在解压缩文件\n);// // 4. 如果被压缩需要进行解压缩同时修改备份信息// FileUtil fu(info.packpath);// fu.UnCompress(info.real_path);// fu.Remove();// info.pack_flag false;// _data-update(info);// printf(解压缩完成\n);// }// bool retrans false;// std::string old_etag;// if (req.has_header(If-Range) true)// {// old_etag req.get_header_value(If-Range);// // 有If-Range字段且这个字段的值与请求文件的最新etag一致则符合断点续传// if (old_etag GetETag(info))// {// retrans true;// }// }// printf(retrans:%d\n, retrans);// // 5. 填充rsp 设置响应头部字段 ETag Accept-Ranges: bytes// printf(填充rsp中\n);// FileUtil fu(info.real_path);// if (retrans false)// {// fu.GetContent(rsp.body);// rsp.set_header(Accept-Ranges, bytes); // 告诉客户端支持断点重传功能// rsp.set_header(ETag, GetETag(info)); // etag 是一个标识文件的数据// rsp.set_header(Content-Type, application/octet-stream); // 告诉客户实际返回的内容的内容类型// rsp.status 200;// }// else// {// // 需要进行断点续传// // httplib内部实现了对于区间请求也就是断点续传请求的处理// // 只需要我们用户将文件所有数据读取到rsp.body中它内部会自动根据请求// // 区间从body中取出指定区间数据进行响应// // 也就是说下边的代码可以省略但是我们需要知道httplib 库给我做了什么工作// fu.GetContent(rsp.body);// rsp.set_header(Accept-Ranges, bytes);// rsp.set_header(ETag, GetETag(info));// rsp.set_header(Content-Type, application/octet-stream);// // rsp.set_header(Content-Range, bytes start-end/fsize);// rsp.status 206;// }// printf(Download 请求完毕\n);// return;// }static void Download(const httplib::Request req, httplib::Response rsp){// 1. 获取客户端请求的资源路径path req.path// 2. 根据资源路径获取文件备份信息printf(收到一个Download请求\n);BackupInfo info;_data-GetOneByURL(req.path, info);// 3. 判断文件是否被压缩如果被压缩要先解压缩,if (info.pack_flag true){FileUtil fu(info.packpath);fu.UnCompress(info.real_path); // 将文件解压到备份目录下// 4. 删除压缩包修改备份信息已经没有被压缩fu.Remove();info.pack_flag false;_data-update(info);}bool retrans false;std::string old_etag;if (req.has_header(If-Range)){old_etag req.get_header_value(If-Range);// 有If-Range字段且这个字段的值与请求文件的最新etag一致则符合断点续传if (old_etag GetETag(info)){retrans true;}}printf(retrans:%d\n, retrans);// 4. 读取文件数据放入rsp.body中FileUtil fu(info.real_path);if (retrans false){fu.GetContent(rsp.body);// 5. 设置响应头部字段 ETag Accept-Ranges: bytesrsp.set_header(Accept-Ranges, bytes);rsp.set_header(ETag, GetETag(info));rsp.set_header(Content-Type, application/octet-stream);rsp.status 200;}else{// httplib内部实现了对于区间请求也就是断点续传请求的处理// 只需要我们用户将文件所有数据读取到rsp.body中它内部会自动根据请求// 区间从body中取出指定区间数据进行响应// std::string range req.get_header_val(Range); bytesstart-endfu.GetContent(rsp.body);rsp.set_header(Accept-Ranges, bytes);rsp.set_header(ETag, GetETag(info));rsp.set_header(Content-Type, application/octet-stream);// rsp.set_header(Content-Range, bytes start-end/fsize);rsp.status 206; // 区间请求响应的是206*****}printf(Download 请求结束\n);}static void Showlist(const httplib::Request req, httplib::Response rsp){// 1. 获取所有的文件备份信息printf(收到一个showlist请求\n);std::vectorBackupInfo arry;_data-GetAll(arry);//std::cout 文件信息准备完毕size: arry.size() std::endl;// 2. 根据这些文件备份信息组织html页面std::stringstream ss;ss htmlheadtitleDownload/title/head;ss bodyh1Download/h1table;for (auto a : arry){ss tr;std::string filename FileUtil(a.real_path).Filename();ss tda href a.url filename /a/td;ss td alignright totimestring(a.atime) /td;ss td alignright a.fsize / 1024 k /td;ss /tr;}ss /table/body/html;//std::cout 文件信息填充完毕开始填写rsq std::endl;// 3. 填充rsp响应rsp.body ss.str();rsp.status 200;rsp.set_header(Content-Type, text/html);printf(showlist请求完毕\n);return;}};}
文章转载自:
http://www.morning.dndjx.cn.gov.cn.dndjx.cn
http://www.morning.krtcjc.cn.gov.cn.krtcjc.cn
http://www.morning.yrgb.cn.gov.cn.yrgb.cn
http://www.morning.itvsee.com.gov.cn.itvsee.com
http://www.morning.gpryk.cn.gov.cn.gpryk.cn
http://www.morning.smpb.cn.gov.cn.smpb.cn
http://www.morning.yjxfj.cn.gov.cn.yjxfj.cn
http://www.morning.drmbh.cn.gov.cn.drmbh.cn
http://www.morning.yzktr.cn.gov.cn.yzktr.cn
http://www.morning.zsfooo.com.gov.cn.zsfooo.com
http://www.morning.bcjbm.cn.gov.cn.bcjbm.cn
http://www.morning.mkpkz.cn.gov.cn.mkpkz.cn
http://www.morning.lmtbl.cn.gov.cn.lmtbl.cn
http://www.morning.jydhl.cn.gov.cn.jydhl.cn
http://www.morning.xbhpm.cn.gov.cn.xbhpm.cn
http://www.morning.nfgbf.cn.gov.cn.nfgbf.cn
http://www.morning.ldqrd.cn.gov.cn.ldqrd.cn
http://www.morning.pmmrb.cn.gov.cn.pmmrb.cn
http://www.morning.fjptn.cn.gov.cn.fjptn.cn
http://www.morning.mrlkr.cn.gov.cn.mrlkr.cn
http://www.morning.yrnll.cn.gov.cn.yrnll.cn
http://www.morning.kflpf.cn.gov.cn.kflpf.cn
http://www.morning.ghxzd.cn.gov.cn.ghxzd.cn
http://www.morning.mkhwx.cn.gov.cn.mkhwx.cn
http://www.morning.mkhwx.cn.gov.cn.mkhwx.cn
http://www.morning.lsqmb.cn.gov.cn.lsqmb.cn
http://www.morning.xxwfq.cn.gov.cn.xxwfq.cn
http://www.morning.mwmtk.cn.gov.cn.mwmtk.cn
http://www.morning.qrlkt.cn.gov.cn.qrlkt.cn
http://www.morning.fkyqm.cn.gov.cn.fkyqm.cn
http://www.morning.plqsz.cn.gov.cn.plqsz.cn
http://www.morning.rpsjh.cn.gov.cn.rpsjh.cn
http://www.morning.shuangxizhongxin.cn.gov.cn.shuangxizhongxin.cn
http://www.morning.xfncq.cn.gov.cn.xfncq.cn
http://www.morning.ldynr.cn.gov.cn.ldynr.cn
http://www.morning.xpqdf.cn.gov.cn.xpqdf.cn
http://www.morning.dmlsk.cn.gov.cn.dmlsk.cn
http://www.morning.qfmns.cn.gov.cn.qfmns.cn
http://www.morning.ymmjx.cn.gov.cn.ymmjx.cn
http://www.morning.pqrhb.cn.gov.cn.pqrhb.cn
http://www.morning.yydeq.cn.gov.cn.yydeq.cn
http://www.morning.tsflw.cn.gov.cn.tsflw.cn
http://www.morning.fxzw.cn.gov.cn.fxzw.cn
http://www.morning.xmhpq.cn.gov.cn.xmhpq.cn
http://www.morning.bttph.cn.gov.cn.bttph.cn
http://www.morning.wanjia-sd.com.gov.cn.wanjia-sd.com
http://www.morning.mrbmc.cn.gov.cn.mrbmc.cn
http://www.morning.qnhpq.cn.gov.cn.qnhpq.cn
http://www.morning.wrlcy.cn.gov.cn.wrlcy.cn
http://www.morning.fhbhr.cn.gov.cn.fhbhr.cn
http://www.morning.knczz.cn.gov.cn.knczz.cn
http://www.morning.jllnh.cn.gov.cn.jllnh.cn
http://www.morning.yzdth.cn.gov.cn.yzdth.cn
http://www.morning.psqs.cn.gov.cn.psqs.cn
http://www.morning.rxtxf.cn.gov.cn.rxtxf.cn
http://www.morning.gltmz.cn.gov.cn.gltmz.cn
http://www.morning.rdwm.cn.gov.cn.rdwm.cn
http://www.morning.zrkp.cn.gov.cn.zrkp.cn
http://www.morning.xwzsq.cn.gov.cn.xwzsq.cn
http://www.morning.rwjh.cn.gov.cn.rwjh.cn
http://www.morning.rmpfh.cn.gov.cn.rmpfh.cn
http://www.morning.rfyff.cn.gov.cn.rfyff.cn
http://www.morning.zhoer.com.gov.cn.zhoer.com
http://www.morning.c7497.cn.gov.cn.c7497.cn
http://www.morning.mztyh.cn.gov.cn.mztyh.cn
http://www.morning.ymsdr.cn.gov.cn.ymsdr.cn
http://www.morning.smdkk.cn.gov.cn.smdkk.cn
http://www.morning.ngkgy.cn.gov.cn.ngkgy.cn
http://www.morning.rmxk.cn.gov.cn.rmxk.cn
http://www.morning.nknt.cn.gov.cn.nknt.cn
http://www.morning.lwtld.cn.gov.cn.lwtld.cn
http://www.morning.wlgpz.cn.gov.cn.wlgpz.cn
http://www.morning.dpjtn.cn.gov.cn.dpjtn.cn
http://www.morning.cwgpl.cn.gov.cn.cwgpl.cn
http://www.morning.zqsnj.cn.gov.cn.zqsnj.cn
http://www.morning.qhrsy.cn.gov.cn.qhrsy.cn
http://www.morning.hhboyus.cn.gov.cn.hhboyus.cn
http://www.morning.jkmjm.cn.gov.cn.jkmjm.cn
http://www.morning.glpxx.cn.gov.cn.glpxx.cn
http://www.morning.skmpj.cn.gov.cn.skmpj.cn
http://www.tj-hxxt.cn/news/241642.html

相关文章:

  • 快速做网站哪家好织梦wap网站模板
  • 80端口被封怎么做网站营业执照注册
  • 深圳企业做网站公qq网站登录入口
  • 甘肃省交通建设集团有限公司网站如何设置标签wordpress
  • 成都网站建设公司司雨人网站建设
  • 怎么做网站主页设计android 写wordpress
  • 做网站嘉兴兼职网站项目建设报告(完整版)
  • 广州市营销型网站建设网站建设费用如何入账
  • 加强网站互动交流平台建设自查汽配外贸论坛
  • 网站每年需要续费吗无锡锡山网站建设
  • 网站后台要求wordpress首页flash
  • 汕头建站程序网络科技公司取名字参考大全
  • 建设直播网站软件深圳企业有哪些
  • 创建手机网站模版抵押网站建设方案
  • 网站设计培训班哪家好著名品牌展厅设计
  • 创一个网站怎样赚钱怎么样做兼职网站
  • SEO案例网站建设公司西宁网站建设的企业
  • 百度网站怎么做信息网业制作
  • 深圳市建设局工程交易中心网站个人如何开发微信小程序
  • 汽车做网站WordPress众筹源码
  • 超炫酷的网站跨境电商平台有哪些新手入门
  • 徐州梦网科技做网站怎么样wordpress边栏
  • 深圳网站建设便宜信科网络用asp.net做的网站框架
  • 金华专业做网站怎样做网站连接
  • 网站设计费报价表营销策略ppt模板
  • 网站视觉wordpress 静态化插件
  • 怎么去掉网站首页尾缀贵阳专业做网站公司有哪些
  • 手机网站微信咨询请人做网站得多少钱
  • 网站模版怎么用超市库存管理软件
  • 网站姐姐做床戏网站长沙望城建设局网站