【Linux】序列化与反序列化

1. "协议"

协议是一种"约定",Socket API 本身只认字节 / 字符串 ,在读写数据时,都是按 "字符串" 的方式来发送接收的,但 Socket 只能发字符串,怎么办?自己定一个协议,或者用现成的标准协议!

协议就是双方约定好的结构化的数据

2. 序列化和反序列化

应用层协议 = 通信双方约定好的数据格式规则

3. 网络计算器代码实现

流程:需要客户端把要计算的两个加数发过去,然后由服务器进行计算,最后再把结果返回给客户端

3.1 整体思路梳理

3.2 Socket封装

Socket.hpp

3.3 定制协议

期望的报文格式:

Protocol.hpp

3.4 完整代码实现

NetCal网络计算器代码

4. Jsoncpp

Jsoncpp是一个用于处理JSON数据的C++库。它提供了将JSON数据序列化为字符串以及从字符串 反序列化为C++数据结构的功能

Json::Value 是Jsoncpp库中的一个重要类,用于表示和操作JSON数据结构

4.1 安装

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

4.2 序列化

序列化指的是将数据结构或对象转换为⼀种格式,以便在网络上传输或存储到文件中。Jsoncpp提供 了多种方式进行序列化

1)直接调用 Json::Value 的成员函数toStyledString()

调试打印用 toStyledString()(简单、好看)

cpp 复制代码
#include <iostream>
#include <string>
#include <jsoncpp/json/json.h>
int main()
{
    Json::Value root;
    root["name"] = "joe";
    root["sex"] = "男";
    std::string s = root.toStyledString();
    std::cout << s << std::endl;
    return 0;
}
$ ./test.exe 
{
 "name" : "joe",
 "sex" : "男"
}

2). StyledWriter

  • 带格式、换行、缩进
  • 可读性好
  • 适合调试、打印日志
cpp 复制代码
#include <iostream>
#include <string>
#include <sstream>
#include <memory>
#include <jsoncpp/json/json.h>
int main()
{
    Json::Value root;
    root["name"] = "joe";
    root["sex"] = "男";
    Json::StyledWriter writer;
    std::string s = writer.write(root);
    std::cout << s << std::endl;
    return 0;
}
$ ./test.exe 
{
 "name" : "joe",
 "sex" : "男"
}

3)使用 Json::FastWriter

  • 它不添加额外的空格和换⾏符。 压缩无格式{"x":10,"y":20}
  • 最快、体积最小
  • 网络传输首选
cpp 复制代码
#include <iostream>
#include <string>
#include <sstream>
#include <memory>
#include <jsoncpp/json/json.h>
int main()
{
    Json::Value root;
    root["name"] = "joe";
    root["sex"] = "男";
    Json::FastWriter writer;
    std::string s = writer.write(root);
    std::cout << s << std::endl;
    return 0;
}
$ ./test.exe 
{"name":"joe","sex":"男"}

4.3 反序列化

反序列化指的是将序列化后的数据重新转换为原来的数据结构或对象。Jsoncpp提供了以下方法进行反序列化

1) Json::Reader

提供详细的错误信息和错误位置

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

int main()
{
    // JSON 字符串
    std::string json_string = "{\"name\":\"张三\", \"age\":30, 
\"city\":\"北京\"}";

    // 解析 JSON 字符串
    Json::Reader reader;
    Json::Value root;

    // 从字符串中读取 JSON 数据
    bool parsingSuccessful = reader.parse(json_string, root);

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

    // 访问 JSON 数据
    std::string name = root["name"].asString();
    int age = root["age"].asInt();
    std::string city = root["city"].asString();

    // 输出结果
    std::cout << "Name: " << name << std::endl;
    std::cout << "Age: " << age << std::endl;
    std::cout << "City: " << city << std::endl;

    return 0;
}
$ ./test.exe 
Name: 张三
Age: 30
City: 北京

2)不推荐使用:Json::CharReader 派生类

仅在需要精细控制解析过程的特殊场景使用,日常开发完全不需要

相关推荐
烟花落o12 小时前
C++ 从 C 到进阶 ②:引用、inline 、nullptr
c++·引用·inline·nullptr·c++入门
liulilittle12 小时前
MOE路由:路由(logits: top-k/8)
c++·人工智能·算法·机器学习·llm
旖旎夜光12 小时前
LeetCode 11:盛最多水的容器(双指针问题) —— 题解
数据结构·c++·算法·leetcode·双指针
qq_4480111612 小时前
C语言中的野指针和空指针
c语言·开发语言·单片机
估值探索者13 小时前
【Python实时盯盘与预警 #08】成交额突然放大2倍?Python窗口比较抓异动
java·开发语言·python
yk 坤帝13 小时前
用Python实现发送《自动周报》实战脚本
开发语言·python
abbgogo15 小时前
OSPF动态路由协议
开发语言·php
我不会插花弄玉15 小时前
15.map,set下:AVL树,红黑树和map,set的封装【由浅入深-C++】
c++·stl
en.en..15 小时前
C 语言嵌入式事件驱动状态机完整教程(枚举配套)
c语言·开发语言
hold?fish:palm15 小时前
20 旋转图像
c++·算法·leetcode