【网络】序列化和反序列化

一、序列化和反序列化

序列化和反序列化是计算机中用于数据存储和传输的重要概念。

1.序列化   (Serialization)

是将数据结构或对象转换成一种可存储或可传输格式的过程。在序列化后,数据可以被写入文件、发送到网络或存储在数据库中,以便在需要时可以再次还原成原始的数据结构或对象。序列化的过程通常涉及将数据转换成字节流或类似的格式,使其能够在不同平台和编程语言之间进行传输和交换。

2.反序列化(Deserialization)

是序列化的逆过程,即将序列化后的数据重新还原成原始的数据结构或对象。反序列化是从文件、网络数据或数据库中读取序列化的数据,并将其转换回原始形式,以便在程序中进行使用和操作。 

3.使用场景

序列化和反序列化在许多场景中都非常有用,例如:

数据存储:将程序中的数据保存到文件或数据库中,以便在以后重新加载和使用。

网络通信:在网络上传输数据时,需要将数据序列化为字节流,以便在接收端进行反序列化。

分布式系统:在分布式系统中,不同计算节点之间需要通过序列化和反序列化来交换数据。

进程间通信:不同进程之间通信时,数据需要在序列化和反序列化之间进行转换。

常见的序列化格式包括 JSON(JavaScript Object Notation)、XML(eXtensible Markup Language)、Protocol Buffers、MessagePack等。每种格式有其优势和适用场景,选择合适的序列化格式取决于具体的应用需求。

二. json

这是我自己写的一个序列化和反序列化协议.但是我们每次自己写协议,任务量太大.所以有两种比较好的方式,一个是json,一个是protobuf.两者相比json比较轻量化,我在这里只介绍json.

#pragma once

#include <iostream>
#include <string>

static const std::string back_space_sep = " ";
static const std::string protocol_sep = "\n";

static std::string Encode(std::string &content)
{
    std::string package = std::to_string(content.size()) + protocol_sep + content + protocol_sep;
    return package;
}

static bool Decode(std::string &package, std::string *content)  // "len"\n"x op y"\n
{
    std::size_t left = package.find(protocol_sep);
    if(left == std::string::npos) return false;

    std::string len_str = package.substr(0, left);
    std::size_t len = stoi(len_str);

    std::string str = package.substr(left + 1, len);
    
    //验证该串是否完整
    std::size_t total_len = len_str.size() + len + 2;
    if(total_len > package.size()) return false;
    
    *content = str;
    package.erase(0, total_len);
    return true; 
}

class Request
{
public:
    Request(int data1, int data2, char op0)
        : x(data1), y(data2), op(op0)
    {}
    Request()
    {}
public:
    bool Serialize(std::string *output)
    {
        //构建报文的有效载荷
        // x op y
        std::string s = std::to_string(x) + back_space_sep + op + back_space_sep + std::to_string(y);

        //封装报头
        //*output = std::to_string(s.size()) + protocol_sep + s;
        *output = s;
        return true;
    }

    bool Deserialize(const std::string &in) // x op y
    {
        std::size_t left = in.find(back_space_sep);
        if(left == std::string::npos) return false;
        std::string part_x = in.substr(0, left);

        std::size_t right = in.rfind(back_space_sep);
        if(right == std::string::npos) return false;
        std::string part_y = in.substr(right + 1);

        if(left + 2 != right) return false;

        op = in[left + 1];
        x = std::stoi(part_x);
        y = std::stoi(part_y);
        return true;
    }

    void DebugPrint()
    {
        std::cout << "新请求构建完成:" << x << " " << op << " " << y << " = ?" <<std::endl;
    }

public:
    // x op y
    int x;
    int y;
    char op;  // + - * / %
};

class Responce
{
public:
    Responce(int res, int c) 
        : result(res), code(c)
    {}
    Responce()
    {}
public:
    bool Serialize(std::string *out)
    {
        //"result code"
        std::string s = std::to_string(result) + back_space_sep + std::to_string(code);

        //*out = std::to_string(s.size()) + protocol_sep + s;
        *out = s;
        return true;
    }

    bool Deserialize(const std::string &in) //"result code"
    {
        std::size_t mid = in.find(back_space_sep);
        if(mid == std::string::npos) return false;
        std::string part_res = in.substr(0, mid);
        std::string part_c = in.substr(mid + 1);

        result = std::stoi(part_res);
        code = std::stoi(part_c);

        return true;
    }

    void DebugPrint()
    {
        std::cout << "结果响应完成, result: " << result << " code: " << code <<std::endl;
    }

public:
    int result; //计算结果
    int code;   //错误码  0:正确
};

1.概念

JSON(JavaScript Object Notation, JS对象简谱)是一种轻量级的数据交换格式。它基于 ECMAScript(European Computer Manufacturers Association, 欧洲计算机协会制定的js规范)的一个子集,采用完全独立于编程语言的文本格式来存储和表示数据。简洁和清晰的层次结构使得 JSON 成为理想的数据交换语言。 易于人阅读和编写,同时也易于机器解析和生成,并有效地提升网络传输效率。

json的样子就是这样

{ 
"people":[ 
{
"firstName": "Brett",            
"lastName":"McLaughlin"        
},      
{        
"firstName":"Jason",
"lastName":"Hunter"
}
]
}

2.Linux下安装第三方库

本次安装在Ubuntu系统下

1.更新源

sudo apt-get update

2.安装

sudo apt-get install libjsoncpp-dev

3.检查安装是否成功

ls /usr/include/jsoncpp/json/

 4.使用

使用的时候包含头文件 #include <jsoncpp/json/json.h>
编译的时候链接库 g++ -ljsoncpp

#include <iostream>
#include <jsoncpp/json/json.h>

// {a:120, b:"123"}
int main()
{
    //序列化
    Json::Value root;
    root["x"] = 100;
    root["y"] = 200;
    root["op"] = '+';
    root["desc"] = "this is a + oper";

    Json::Value test;
    test["haha"] = "haha";
    test["hehe"] = "hehe";

    root["test"] = test; //也可以加Value对象

    Json::FastWriter w;
    //Json::StyledWriter w;
    std::string res = w.write(root);

    std::cout <<res << std::endl;

    //反序列化
    Json::Value v;
    Json::Reader r;
    r.parse(res, v);

    int x = v["x"].asInt();
    int y = v["y"].asInt();
    char op = v["op"].asInt();
    std::string desc = v["desc"].asString();

    Json::Value temp = v["test"];
    std::string str = temp["haha"].asString() + ":" + temp["hehe"].asString();

    std::cout << desc << ": " << x << op << y << std::endl;
    std::cout << str << std::endl;

    return 0;
}

三.源代码展示

test605 · AoDong/Linux-test - 码云 - 开源中国 (gitee.com)

  • 6
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值