【网络】自定义协议 | 序列化和反序列化 | Jsoncpp

news2024/10/7 12:22:08

本文首发于 慕雪的寒舍

以tcpServer的计算器服务为例,实现用jsoncpp来进行序列化和反序列化

阅读本文之前,请先阅读 自定义协议 | 序列化和反序列化 | 以tcpServer为例

1.安装jsoncpp

我所用的系统是centos7.6,先用下面的命令查找相关的包

sudo yum list | grep jsoncpp-devel

显示出来的包如下

Repository epel is listed more than once in the configuration
jsoncpp-devel.x86_64                0.10.5-2.el7           @epel 

随后安装这个包

sudo yum install jsoncpp

不知道为什么,安装jsoncpp-devel.x86_64显示找不到相关包

或者采用下面的两个命令

sudo yum install epel-release
sudo yum install jsoncpp-devel

如果执行完毕后显示找不到jsoncpp,尝试重新安装epel-release

image-20230404123816637

刚开始我显示epel已经安装,但是找不到jsoncpp这个包,我在重新安装了epel后就能正常安装了

sudo yum rm epel-release
sudo yum install epel-release
sudo yum install jsoncpp-devel

如下图,正常查找到并安装完毕

image-20230404123834144

在centos8下,安装完毕后路径如下

$ ls /usr/include/json
allocator.h  assertions.h  autolink.h  config.h  features.h  forwards.h  json.h  reader.h  value.h  version.h  writer.h

1.1 什么是json?

json是一个kv键值对的序列化方式,每一个key都对应了一个value

{
	"data": "value"
}

这就有点类似c++中的map,不过json能做的更多

{
	"data1": "value",
	"data2": {
		"key1":"value1",
		"key2":"value2",
         "key3":0,
         "key4":true
	}
}

json可以在里面嵌套添加更多的内容,不管是字符串还是整形,还能是bool类型的true/false

因为json对反序列化序列化的控制很是不错,可读性也很好,所以被广泛使用!

相比于自己写一个序列化方式,直接用别人的轮子,也不错👻

类似的序列化框架还有xml

2.代码示例

2.1 序列化

相比我们自己写的序列化方式,json的使用简单多了

void serialize(std::string& out)
{
     //使用jsoncpp的代码
    Json::Value root;
    root["x"] = _x;
    root["y"] = _y;
    root["op"] = _ops;

    Json::FastWriter fw; // 这个是写成一行,对于计算机来说处理的负担小
    // Json::StyledWriter fw; // 这个会进行格式化,更好看(但是内容没差距)
    out = fw.write(root);
}

对于fw.write(root),其返回值是一个string,也方便我们接收

image-20230212135543386

其中FastWriterStyledWriter有一点区别,如下

//FastWriter
{"data": "value"}
//StyledWriter
{
	"data": "value"
}

简单来说,StyledWriter会对我们的kv键值对进行格式化,更方便人类的阅读。而FastWriter是直接写成一整行,在传输的时候会方便一点(因为不需要\n

2.2 反序列化

反序列化需要一个Reader来读取字符串,并将其内容根据键值隐射给成员变量

bool deserialize(const std::string &in)
{
    //json
    Json::Value root;
    Json::Reader rd;
    rd.parse(in, root);
    _x = root["x"].asInt();
    _y = root["y"].asInt();
    _ops = root["op"].asInt();
}

3.测试

因为jsoncpp是一个第三方库,我们链接的时候需要加上命令-ljsoncpp

tcpServer:tcpServer.cpp
	g++ -o $@ $^ -std=c++11 -lpthread -ljsoncpp

发送消息后,可以看到,json帮我们格式化为如下形式的字符串

{"op":43,"x":1,"y":200}
{"op":43,"x":333,"y":234}

image-20230212140924067

4.gcc给予宏定义

为了方便对序列化采用的方式进行控制,这里我使用了预处理指令ifdef/endif来进行判断,只要我们在文件头定义了MYPROTOCOL,这里就会采用我们自己的写的序列化方式,否则采用json

#define MYPROTOCOL 1  //如果define了这个,那就使用自己的代码

image-20230212182113854

4.1 命令行

但是在文件里面修改define还是不太方便,我们可以直接采用gcc的命令行参数的方式,进行define的插入(这么做之前,要先删除文件中对MYPROTOCOL的define)

g++ -DMYPROTOCOL tcpServer.cpp -o tcpServer -lpthread -ljsoncpp
g++ -DMYPROTOCOL tcpClient.cpp -o tcpClient -lpthread -ljsoncpp

可以看到,不加编译指令编译出来的服务器,采用的是json的方式来序列化

image-20230212182627766

添加了之后,就是用我们自己写的序列化方式来序列化了

image-20230212182919150

4.2 makefile

因此,我们可以修改makefile来实现这一点

.PHONY:all
all:tcpClient tcpServer
MYSELF=-DMYPROTOCOL

tcpClient: tcpClient.cpp
	g++ $(MYSELF) -o $@ $^ -std=c++11 -lpthread -ljsoncpp
tcpServer:tcpServer.cpp
	g++ $(MYSELF) -o $@ $^ -std=c++11 -lpthread -ljsoncpp

.PHONY:clean
clean:
	rm -f tcpClient tcpServer

当我们需要用自己协议的时候,就在最前面加上

MYSELF=-DMYPROTOCOL

否则直接删除这个定义,或者注释掉后面的内容,就能采用jsoncpp

MYSELF=#-DMYPROTOCOL

这样就方便一些了

image-20230212183456024

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/846423.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

AST还原实战| 实战还原一个22M的混淆js大文件

关注它,不迷路。 本文章中所有内容仅供学习交流,不可用于任何商业用途和非法用途,否则后果自负,如有侵权,请联系作者立即删除! 1. 需求分析 之前有星友发了这个大文件在群里: https://t.zsxq.com/10…

CountDownLatch 使用详情

CountDownLatch 是 Java.util.concurrent 包下的一个类,它可以用来实现一个或多个线程等待其他线程完成后再继续执行的场景。 CountDownLatch 类中有一个计数器,每次调用 countDown() 方法计数器的值减1,当计数器的值变为0时,调用…

面向大模型的存储加速方案设计和实践

这是 AI 大底座系列云智公开课的第三期内容。前两期我的两位同事已经向大家介绍了高性能网络和 GPU 容器虚拟化的相关内容。今天我们把目光聚焦在存储方向,一起来看看面向大模型的存储加速方案的设计和实践。 今天将从以下三个方面来展开这次分享: 介绍…

APP外包开发的Flutter框架

Flutter 是一种流行的开源UI框架,由谷歌开发,用于构建跨平台的移动应用程序。它使用一套统一的代码库,可以在多个平台上(如Android、iOS、Web、桌面等)保持一致的外观和行为。今天和大家分享一些基于 Flutter 开发的常…

CI/CD持续集成持续发布(jenkins)

1.背景 在实际开发中,我们经常要一边开发一边测试,当然这里说的测试并不是程序员对自己代码的单元测试,而是同组程序员将代码提交后,由测试人员测试; 或者前后端分离后,经常会修改接口,然后重新…

【CSS】说说响应式布局

目录 一、是什么 二、怎么实现 1、媒体查询 2、百分比 3、vw/vh 4、小结 三、总结 一、是什么 响应式设计简而言之,就是一个网站能够兼容多个终端——而不是为每个终端做一个特定的版本。 响应式网站常见特点: 同时适配PC 平板 手机等…

代码随想录 - 数组

数组是存放在连续内存空间上的相同类型数据的集合。 注意: 数组下标都是从0开始的。数组内存空间的地址是连续的 数组的在内存空间的地址是连续的,所以在删除或者增添元素的时候,就难免要移动其他元素的地址。 例如删除下标为3的元素&#x…

SpringMVC的注解

文章目录 前言前期准备ResponseBody 返回JSONRequestMapping 映射控制器GetMapping、PostMapping 前言 提示:这里可以添加本文要记录的大概内容: SpringMVC框架只需要少量的配置即可快速实现Web应用程序开发,不需要大量的XML配置文件。 不…

【ES】笔记-简化对象写法箭头函数及声明特点

简化对象写法&箭头函数及声明特点 简化对象写法箭头函数及声明特点 简化对象写法 ES6 允许在大括号里面,直接写入变量和函数,作为对象的属性和方法.这样的书写更加简介 声明变量和和函数 let name南昌大学;let changefunction(){console.log(我可以改…

如何使用Kafka构建事件驱动的架构

事件驱动的架构(EDA)是一种软件设计模式,它关注事件的生成、检测和使用,以支持高效和可扩展的系统。在EDA中,事件是组件之间通信的主要手段,允许它们实时交互和响应更改。这种架构促进了松散耦合、可扩展性和响应性,使…

Semantic Kernel 入门系列:突破提示词的限制

无尽的上下文 LLM对自然语言的理解和掌握在知识内容的解读和总结方面提供了强大的能力。 但是由于训练数据本身来自于公共领域,也就注定了无法在一些小众或者私有的领域能够足够的好的应答。 因此如何给LLM 提供足够多的信息上下文,就是如今的LLM AI应…

el-table合并表头、动态合并列、合并尾部合计

在有些情况下,我们会有合并表头、合并列、合并尾部合计的需求,这篇文章是为了记录,如何进行合并,方便日后翻阅。 效果图 el-table合并表头 el-table合并列(动态合并) el-table合并尾部合计 el-table合并表…

64x8com的LCD液晶屏驱动芯片IC,VK1625完美兼容市面所有1625驱动芯片

产品型号:VK1625 产品品牌:VINKA/元泰 封装形式:QFP100 LQFP100 DICE/裸片 COB邦定片 定制COG 专业工程服务,技术支持!用芯服务! 概述: VK1625B是一个64x8的LCD駆动器. 可软件程控使其适用于多样化的…

在 Amazon SageMaker 上使用 Amazon Inferentia2 实现 AI 作画

在前一篇文章中,我们介绍了如何使用 Amazon EC2 Inf2 实例部署大语言模型,有不少用户询问 Amazon Inf2 实例是否支持当下流行的 AIGC 模型,答案是肯定的。同时,图片生成时间、QPS、服务器推理成本、如何在云中部署,也是…

【数学建模】--聚类模型

聚类模型的定义: “物以类聚,人以群分”,所谓的聚类,就是将样本划分为由类似的对象组成的多个类的过程。聚类后,我们可以更加准确的在每个类中单独使用统计模型进行估计,分析或预测;也可以探究不…

bigemap如何添加高清在线地图?

说明:批量添加可以同时添加多个在线地图,一次性添加完成(批量添加无法验证地址是否可以访问) 添加后如下图: 第一步 : 制作地图配置文件:选择添加在线地图(查看帮助)。 …

Linux6.33 Kubernetes kubectl详解

文章目录 计算机系统5G云计算第三章 LINUX Kubernetes kubectl详解一、陈述式资源管理方法1.基本信息查看2.项目的生命周期:创建-->发布-->更新-->回滚-->删除 二、声明式管理方法 计算机系统 5G云计算 第三章 LINUX Kubernetes kubectl详解 一、陈述…

【力扣每日一题】2023.8.7 反转字符串

目录 题目: 示例: 分析: 代码: 题目: 示例: 分析: 题目给我们一个字符数组形式的字符串,让我们直接原地修改反转字符串,不必返回。 给出的条件是使用O(1)的额外空间…

JS进阶-Day3

🥔:永远做自己的聚光灯 JS进阶-Day1——点击此处(作用域、函数、解构赋值等) JS进阶-Day2——点击此处(深入对象之构造函数、实例成员、静态成员等;内置构造函数之引用类型、包装类型等) 更多JS…

工业以太网交换机-SCALANCE X200 环网组态

1.概述 SCALANCE X200 系列交换机自从2004年8月推入市场,当时交换机只能接入环网,不能做环网管理器。在各个工业现场得到了广泛的应用。2007年5月发布了X200系列新的硬件版本平台,普通交换机可以用HSR(高速冗余)方法做…