Linux -- 自定义协议体会序列化和反序列化

ops/2025/1/14 18:01:01/

思路介绍

网络版计算器:

1、客户端发送 两个操作数 和 操作符

2、根据协议,在发送时,对数据进行序列化,再加上报头,形成 请求 并发送给 服务器

3、服务器收到 请求 后,判断收到的 请求 是否完整

4、若 请求 完整,则从 请求 中分离出有效载荷,再对有效载荷进行 反序列化

5、服务器处理完数据后,把 结果 进行序列化,并加上报头,作为 应答 发送给客户端;

6、客户端判断收到的 应答 是否完整;

7、 应答 完整,对 应答 进行解析,从有效载荷中取出计算结果。

gitee

net_cal · zihuixie/Linux_Learning - 码云 - 开源中国icon-default.png?t=O83Ahttps://gitee.com/zihuixie/linux_-learning/tree/master/net_cal

主要代码

序列化 && 反序列化 -- Protocol.hpp

#pragma once#include <iostream>
#include <string>
#include <jsoncpp/json/json.h>
#include <unistd.h>
#include<memory>//指定协议namespace protocol_ns
{const std::string SEP = "\r\n"; // 分隔符// 添加报头(有效载荷已经序列化)// 报文:len\r\n{       }\r\nstd::string Encode(const std::string &json_str){int json_str_len = json_str.size(); // 计算长度std::string proto_str = std::to_string(json_str_len); // 报文proto_str += SEP;      // 分隔符proto_str += json_str; // 有效载荷proto_str += SEP;return proto_str;}// len\r\n{// len\r\n{       }// len\r\n{       }\r\n// len\r\n{       }\r\nlen\r\n{// len\r\n{       }\r\nlen\r\n{       }\r// len\r\n{       }\r\nlen\r\n{       }\r\n// len\r\n{       }\r\nlen\r\n{       }\r\nlen\r// len\r\n{       }\r\nlen\r\n{       }\r\nlen\r\n{       }\r\n//  分离出有效载荷(但收到的报文不一定是完整的,判断收到的报文中有一个完整的报文,就可以进行分离)std::string Decode(std::string &inbuffer){auto pos = inbuffer.find(SEP);// 报文不完整if (pos == std::string::npos)return std::string();std::string len_str = inbuffer.substr(0, pos);if (len_str.empty())return std::string();int packlen = std::stoi(len_str); // 有效载荷的长度int total = packlen + 2 * SEP.size() + len_str.size(); // 完整报文的长度if (inbuffer.size() < total)return std::string(); // 不是完整报文std::string package = inbuffer.substr(pos + SEP.size(), packlen); // 有效载荷inbuffer.erase(0, total); // 在报文中去掉完整的一段,避免重复处理return package;}// 请求,客户端向服务器发送请求class Request{public:Request(){}Request(int x, int y, char oper): _x(x), _y(y), _oper(oper){}// 序列化,out 是输出型参数// 客户端发送请求时,将请求序列化bool Serialize(std::string *out){Json::Value root;root["x"] = _x;root["y"] = _y;root["oper"] = _oper;Json::FastWriter writer;*out = writer.write(root); // 将 root 序列化为字符串return true;}// 反序列化// 服务器收到请求,将请求反序列化bool Deserialize(const std::string &in){Json::Value root;Json::Reader reader; // 从字符串中读取 Json 数据bool res = reader.parse(in, root); // 解析// 解析失败if (!res)return false;// 解析成功_x = root["x"].asInt();_y = root["y"].asInt();_oper = root["oper"].asInt();return true;}public:int _x;     // 左操作数int _y;     // 右操作数char _oper; // 操作符};// 应答// 服务器处理完请求,向客户端发送应答class Response{public:Response(){}Response(int result, int code): _result(result), _code(code){}// 序列化,out 是输出型参数// 将应答序列化,发送给客户端bool Serialize(std::string *out){Json::Value root;root["result"] = _result;root["code"] = _code;Json::FastWriter writer;*out = writer.write(root); // 将 root 序列化为字符串return true;}// 反序列化// 客户端收到应答,将应答反序列化bool Deserialize(const std::string &in){Json::Value root;Json::Reader reader; // 从字符串中读取 Json 数据bool res = reader.parse(in, root); // 解析// 解析失败if (!res)return false;// 解析成功_result = root["result"].asInt();_code = root["code"].asInt();return true;}public:int _result; // 运算结果int _code;   // 结果是否可信,0:可信,1:除0,2:非法操作};// 工厂,创造数据// 模拟客户端class Factory{public:Factory(){srand(time(nullptr) ^ getpid());opers = "+/*/%^&|";}std::shared_ptr<Request> BuildRequest(){int x = rand() % 10 + 1;usleep(x * 10);int y = rand() % 5; usleep(y * x * 5);char oper = opers[rand() % opers.size()];std::shared_ptr<Request> req = std::make_shared<Request>(x, y, oper);return req;}std::shared_ptr<Response> BuildResponse(){return std::make_shared<Response>();}~Factory(){}private:std::string opers;};
}

 

运行结果:

服务器

客户端:


http://www.ppmy.cn/ops/150068.html

相关文章

HTML实战课堂之简单的拜年程序

一、目录&#xff1a; &#xfffc;&#xfffc; 一、目录&#xff1a; 二、祝福 三&#xff1a;代码讲解 &#xff08;1&#xff09;详细解释&#xff1a; 1.HTML部分 2. CSS部分 三、运行效果&#xff08;随机截图&#xff09;&#xff1a; 四、完整代码&#xff1a; 二、祝福…

3Hive数据抽样

3Hive数据抽样 1 随机抽样2 块抽样3 桶表抽样 当数据规模不断膨胀时&#xff0c;我们需要找到一个数据的子集来加快数据分析效率。因此我们就需要通过筛选和分析数据集为了进行模式 & 趋势识别。目前来说有三种方式来进行抽样&#xff1a;随机抽样&#xff0c;桶表抽样&…

Node.js——fs(文件系统)模块

个人简介 &#x1f440;个人主页&#xff1a; 前端杂货铺 &#x1f64b;‍♂️学习方向&#xff1a; 主攻前端方向&#xff0c;正逐渐往全干发展 &#x1f4c3;个人状态&#xff1a; 研发工程师&#xff0c;现效力于中国工业软件事业 &#x1f680;人生格言&#xff1a; 积跬步…

PySpark用sort-merge join解决数据倾斜的完整案例

假设有两个大表 table1 和 table2 &#xff0c;并通过 sort-merge join 来解决可能的数据倾斜问题。 from pyspark.sql import SparkSession from pyspark.sql.functions import col# 初始化SparkSession spark SparkSession.builder.appName("SortMergeJoinExample&quo…

Blazor开发复杂信息管理系统的优势

随着现代企业信息管理需求的不断提升&#xff0c;开发高效、易维护、可扩展的系统变得尤为重要。在这个过程中&#xff0c;Blazor作为一种新兴的Web开发框架&#xff0c;因其独特的优势&#xff0c;逐渐成为开发复杂信息管理系统的首选技术之一。本文将结合Blazor在开发复杂信息…

IIS安全配置基线

IIS安全配置基线 1. 限制目录的执行权限2. 开启日志记录功能3. 自定义错误页面4. 关闭目录浏览功能5. 停用或删除默认站点6. 删除不必要的脚本映射7. 专职低权限用户运行网站8. 在独立的应用程序池中运行网站 IIS&#xff08;Internet Information Services&#xff09;安全部署…

【C语言】标准IO

目录 1. 什么是标准IO 1.1概念 1.2特点 1.3 操作 2. 缓存区 3. 函数接口 3.1打开文件fopen 3.2关闭文件 3.3读写文件操作 3.3.1每次读写一个字符&#xff1a;fgetc()、fputc() a. 针对文件 b. 针对终端 3.3.2 每次一串字符的读写fgets()和fputs() c. 针对终端 d…

基于微信小程序的书籍销售系统设计与实现(LW+源码+讲解)

专注于大学生项目实战开发,讲解,毕业答疑辅导&#xff0c;欢迎高校老师/同行前辈交流合作✌。 技术范围&#xff1a;SpringBoot、Vue、SSM、HLMT、小程序、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、安卓app、大数据、物联网、机器学习等设计与开发。 主要内容&#xff1a;…