Linux笔记---协议定制与序列化/反序列化

1. 协议

我们在Linux笔记---计算机网络概述-CSDN博客中已经谈过协议的基本概念了,这里就不再复述。

放到程序员编程的角度来说,协议规定的就是如何在网络当中传输结构化的数据

显然,将结构化的数据直接以bit流的方式传输是不现实的,且不说各种语言对于同一种结构体的解释与编码是否相同,就是同种类型的变量是否兼容都是未知数。

我们不能指望与你通信的远端和你使用的是同一种语言。所以,我们需要将结构化的数据转换为可传输的格式,字符串就是我们的不二选择。

因为字符的编码是有独立的标准规定的,例如ASCII、base64。

协议就是用来规字符串与结构化数据之间如何相互转换的。遵守相同的协议,就是双方通信的前提。

2. 序列化与反序列化

  • 序列化:将结构化的数据转换字符串(如字节流、JSON、XML 等)的过程。
  • 反序列化:将序列化后的数据流恢复为内存中原始对象的过程,是序列化的逆操作。

3. JSONCPP库

我们可以自己约定如何进行序列化与反序列化,但是显然使用已有的开源库更加方便。

JSONCPP 是一款开源的 C++ 库 ,专门用于处理JSON(JavaScript Object Notation)数据格式,提供了 JSON 数据的解析、生成、修改和查询等核心功能。它具有跨平台、API 简洁、稳定性高的特点,广泛应用于 C++ 项目中(如接口数据交互、配置文件读写、日志格式化等场景)。

所谓JSON数据格式,就是上面的图中所显示的那样的字符串:用一个大括号将一个结构化的数据括起来,将其中的变量名和数值以字符串键值对的形式存储。

安装方式:

bash 复制代码
ubuntu:sudo apt-get install libjsoncpp-dev 
Centos: sudo yum install jsoncpp-devel

3.1 核心数据结构

JSONCPP 的核心设计围绕两个关键类展开,几乎所有操作都基于这两个类:

|--------------------|-----------------------------------------------------------------------|
| 类名 | 作用说明 |
| Json::Value | 表示一个 JSON 数据节点,可存储 JSON 支持的所有类型(对象、数组、字符串、数字、布尔、null),支持嵌套结构。 |
| Json::Document | 继承自 Json::Value,专门用于表示完整的 JSON 文档(根节点通常是对象或数组),提供解析字符串 / 文件的入口。 |

3.2 简单用法---序列化

首先,我们需要定义出一个Json::Value对象,使用map的同款写法可以定义键值对:

cpp 复制代码
#include <jsoncpp/json/json.h>

int main()
{
    Json::Value root;
    root["name"] = "张三";
    root["age"] = 18;
    root["gender"] = 'M';
}

接下来,要将root序列化可以有如下三种方式:

3.2.1 Json::Value 的 toStyledString

将 Json::Value 对象直接转换为格式化的 JSON 字符串,"Styled" 代表生成的JSON字符串会添加额外的空格与换行符来确保JSON串的可读性:

cpp 复制代码
#include <jsoncpp/json/json.h>
#include <iostream>

int main()
{
    Json::Value root;
    root["name"] = "张三";
    root["age"] = 18;
    root["gender"] = 'M';
    std::string json_str = root.toStyledString();
    std::cout << json_str << std::endl;
}

输出结果:
{
    "name" : "张三",
    "age" : "18",
    "gender" : "M"
}

这种风格的JSON串相对来说可读性较高。

3.2.2 Json::FastWriter 的 write

相对于 "Styled",FastWriter转换出的JSON串则不添加额外的空格和换行符:

cpp 复制代码
#include <jsoncpp/json/json.h>
#include <iostream>

int main()
{
    Json::Value root;
    root["name"] = "张三";
    root["age"] = 18;
    root["gender"] = 'M';
    Json::FastWriter writer;
    std::string json_str = writer.write(root);
    std::cout << json_str << std::endl;
}

输出结果:
{"name":"张三","age":"18","gender":"M"}

3.3 简单用法---反序列化

3.3.1 Json::Reader 的 parse

将JSON串反序列化为Json::Value对象:

cpp 复制代码
#include <jsoncpp/json/json.h>
#include <iostream>

int main()
{
    // JSON字符串
    std::string json_str = "{\"name\":\"张三\", \"age\":18, \"gender\":\"M\"}";
    
    Json::Reader reader; 
    Json::Value root;

    if(!reader.parse(json_str, root))
    {
        // 解析失败,输出错误信息 
        std::cout << "Failed to parse JSON: " << reader.getFormattedErrorMessages() << std::endl; 
        return 1;
    }

    // 访问Value对象的键值需要通过函数转化
    std::string name = root["name"].asString();
    int age = root["age"].asInt();
    char gender = root["gender"].asInt();
    
    std::cout << "name : " << name << endl;
    std::cout << "age : " << age << endl;
    std::cout << "gender : " << gender << endl;   
}

输出结果:
name : 张三
age : 18
gender : M
相关推荐
Macbethad12 分钟前
用流程图去描述一个蓝牙BLE数字钥匙的初始化连接过程
服务器·网络·流程图
喜欢吃豆2 小时前
[特殊字符] 深入解构 Assistants API:从“黑盒”抽象到“显式”控制的架构演进与终极指南
网络·人工智能·自然语言处理·架构·大模型
好望角雾眠2 小时前
第四阶段C#通讯开发-5:TCP
网络·笔记·网络协议·tcp/ip·c#
深圳南柯电子2 小时前
深圳南柯电子|医疗电子EMC整改:助医疗器械安全稳定的关键环节
网络·人工智能·安全·互联网·实验室·emc
三品吉他手会点灯2 小时前
stm32f103学习笔记-16-RCC(第2节)-讲解系统时钟配置函数SetSysClockTo72()
笔记·stm32·单片机·嵌入式硬件·学习
仙人掌_lz3 小时前
Kimi Linear 论文阅读笔记:第一次“线性注意力”全面胜过全注意力
论文阅读·笔记
wdfk_prog3 小时前
[Linux]学习笔记系列 -- [kernel]cpu
linux·笔记·学习
报错小能手3 小时前
计算机网络自顶向下方法41——网络层 自治系统内部的路由选择:开放最短路优先(OSPF)设置OSPF链路权值
网络·计算机网络·智能路由器
国科安芯4 小时前
多输出电压条件下同步整流效率测试与优化
网络·单片机·嵌入式硬件·安全
li星野4 小时前
打工人日报#20251109
笔记