序列化和反序列化

本文介绍了在网络通信中结构体如何通过序列化和反序列化进行传输。序列化是将结构体转换为便于传输的字符串,而反序列化则是将接收到的字符串还原为结构体。通过JSON库进行示例演示,展示了如何在C++中实现这一过程,强调了序列化和反序列化在方便传输和解耦合方面的优势。
摘要由CSDN通过智能技术生成

在网络通信的过程中,我们要传递的可能不仅仅只是一个字符串,我们可能需要传更为复杂的结构,比如结构体类型,这种时候我们要用到序列化和反序列化。

假设张三和李四在用QQ聊天,张三给李四发了条消息“你好,我是张三”,这个时候,看起来像是只发了一个字符串,实际上,张三的昵称、发送消息的时间都要发送到李四的主机上。


目录

一、什么是序列化和反序列化

二、为什么需要序列化和反序列化(序列化和反序列化的优点)

1、方便传输

2、实现应用层显示和网络传输的解耦

三、如何序列化和反序列化?

1、安装jsoncpp-devel

2、序列化(结构体 转化成 json字符串)

(1) 准备工作:声明结构体

(2) 开始序列化

3、反序列化(json字符串 转化成 结构体)


一、什么是序列化和反序列化

因为结构体不便于传输,一般需要将结构体转化为一个“长的字符串”,然后再送入网络,这个过程我们称为序列化。

相对应的,李四那边在接收的时候,需要将这个长字符串转化为对方能够识别的形式,如结构体,这个过程我们称为反序列化。

二、为什么需要序列化和反序列化(序列化和反序列化的优点)

1、方便传输

介于结构体对齐原则,结构化的数据不便于用于网络传输

或许你觉得,既然整个结构体传输不行,那就将结构体的每个成员以字符串的形式一个一个传过去,这么做理论上可行,但是一台主机可能会收到多个主机发来的数据,这个时候,就很难区分是哪个主机发的数据。

2、实现应用层显示和网络传输的解耦

假设张三发送一个字符串 "10 + 20",让李四去计算,如果不经过序列化,而是直接发送的话,传递确实很方便,但是站在李四的角度,解析的成本可太高了。

如果我们将一个结构体转化为字符串(即序列化),李四接收的时候,再转化回结构体,这样的话,李四无需知道这个字符串是如何解析的。因为李四和张三手里的东西是一样的,下面只要定好协议,让李四知道传过来的东西怎么使用即可。这就实现了网络传输和上层显示的解耦!!

三、如何序列化和反序列化?

为了实现序列化和反序列化,前人已经有了相应的处理方案,比如xml、json、protocbuff等,这里主要介绍将结构体类型转化为json格式,以及json转结构体类型。

1、安装jsoncpp-devel

根据不同的用户类型,自行选择对应的安装方式

sudo yum install -y jsoncpp-devel        //普通用户
yum install -y jsoncpp-devel             //超级用户

安装成功输入如下指令查看是否有对应的头文件

2、序列化(结构体 转化成 json字符串)

(1) 准备工作:声明结构体

假设现在要将一个结构体传输给对面,下面就先声明一个简单的结构体

//送入网络的,我们作为请求
typedef struct Request{
    int x;
    char op;
    char* msg;
} request_t;

(2) 开始序列化

为了理解这个过程,我以我们熟知的动画为例。海绵宝宝准备好了原材料root,放到铁板上煎,经过一些操作,就得到了一个汉堡。

#include <jsoncpp/json/json.h>
#include <iostream>
using namespace std;

int main(){
    request_t req = {10,'+',"Hello,world"};        //初始化结构体

    Json::Value root;               //原材料root             
    root["datax"] = req.x;          //放到铁板上的指定位置
    root["dataop"] = req.op;
    root["datamsg"] = req.msg;

    Json::FastWriter writer;
    //Json::StyledWriter writer;     //这两种写法都可以,至于区别,可以看看打印的结果
    std::string json_str = writer.write(root);    //汉堡制作完成
    return 0;
}

测试结果如下:

======================= StyledWriter =======================

======================= FastWriter =======================

3、反序列化(json字符串 转化成 结构体)

现在痞老板偷到了 蟹老板的独家汉堡,痞老板用高科技的机器分解了这个汉堡,将分解成了原材料的状态,放在托盘上,以便于观察到底用了哪些材料来制作汉堡。

#include <jsoncpp/json/json.h>
#include <iostream>
using namespace std;

int main(){
    //中间的引号需要使用'\'转义
    std::string json_str = "{\"datamsg\":\"Hello,world\",\"dataop\":43,\"datax\":10}";
    Json::Reader reader;
    Json::Value root;

    reader.parse(json_str,root);    //若转化为root以后不便于参数传递,下面填到req里
    request_t req;
    req.x = root["datax"].asInt();    //root中每个key对应的value都是Json::Value类型
    req.op = root["dataop"].asInt();
    req.msg = root["datamsg"].asString().c_str();

    cout<<req.x<<" "<<req.op<<" "<<req.msg<<endl;
    return 0;
}

测试结果如下:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值