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
相关推荐
风行南方1 小时前
密码学之分组密码
网络·密码学
dexi.Chi 攻城狮1 小时前
SQL层次查询语法
经验分享·笔记·sql
艾莉丝努力练剑2 小时前
OpenCode AI 编程:Ubuntu 24.04 环境安装与使用指南
linux·服务器·网络·人工智能·tcp/ip·ubuntu
HERR_QQ2 小时前
强化学习的数学原理 学习笔记
人工智能·笔记·学习·自动驾驶
谷雪_6583 小时前
Linux 网络命名空间:从内核原理到企业级容器网络架构全景实战
linux·网络·架构
liulilittle3 小时前
KCC 拥塞控制算法缺陷修复记录(26/07/05)
网络·tcp/ip·计算机网络·c·信息与通信·tcp·通信
Tian_Hang3 小时前
Eclipse Ditto 的权限策略
java·服务器·前端·网络·ide·ubuntu·eclipse
ai生成式引擎优化技术4 小时前
从知识连接到智能组织:WSaiOS认知网络的理论框架与系统设计摘要
网络·python·plotly·django·pygame
冰暮流星4 小时前
flask之http请求方法
网络·网络协议·http
K成长日志5 小时前
BLE协议之设备地址
网络·物联网·网络协议·嵌入式·蓝牙·ble