网络编程中的序列化、反序列化与协议

news/2024/12/23 7:16:27/

网络编程中的序列化、反序列化与协议

  • 1. 序列化和反序列化的概念
  • 2. 序列化、反序列化与协议的关系
  • 3. JSON与网络通信

在网络编程中,序列化和反序列化与协议密切相关,它们共同构成了数据在网络中传输的基础。本文将详细介绍序列化、反序列化以及它们与协议之间的关系,以及它们在网络通信中的应用。

1. 序列化和反序列化的概念

序列化是将对象或数据结构转换为字节流或其他可传输的格式的过程,以便在网络上传输或持久化存储。序列化后的数据可以以一种结构化的形式传输,使得接收方能够准确地解析和还原原始数据。

反序列化则是将序列化后的数据重新转换为原始对象或数据结构的过程,以便接收方能够使用和理解这些数据。

2. 序列化、反序列化与协议的关系

在网络通信中,协议起着制定通信规则和格式的作用,它规定了数据在网络上传输的格式、传输方式以及通信的行为。序列化和反序列化与协议密切相关:

协议规范数据格式:
协议规定了数据在网络上传输的格式和规范,包括数据的结构、编码方式、标识符等。序列化和反序列化需要按照协议规定的格式来进行,以确保数据在传输过程中能够被正确解析和处理。

序列化与网络协议:
序列化将数据转换为可以在网络上传输的格式,而网络协议则负责指定数据在网络中的传输方式和规则。序列化后的数据需要符合网络协议的规范,以便能够在网络中传输和解析。

反序列化与数据解析:
接收方在接收到数据后,需要进行反序列化操作将数据还原为原始格式。这个过程也涉及到协议的解析,接收方需要按照协议规定的格式来解析数据,以确保能够正确地处理和使用数据。

代码示例:

class request
{
public:request(const int &x, const int &y, const char op): x_(x), y_(y), op_(op){}request(){}// 序列化请求对象为格式为 "x + y" 的字符串bool Serialize(string *out){// 将请求对象的参数转换为字符串,并按照指定格式拼接起来*out = to_string(x_);         // 将 x_ 转换为字符串并存储在 out 中*out += blank_spaces;         // 添加空格*out += op_;                  // 添加操作符*out += blank_spaces;         // 添加空格*out += to_string(y_);        // 将 y_ 转换为字符串并追加在 out 后面return true;                  // 序列化成功}// 反序列化字符串为请求对象bool Deserialize(const string &in){int lpos = in.find(blank_spaces); // 查找第一个空格的位置if (lpos == string::npos)return false;                  // 如果找不到空格,解析失败int rpos = in.rfind(blank_spaces); // 查找最后一个空格的位置if (rpos == string::npos)return false; // 如果找不到空格,解析失败x_ = stoi(in.substr(0, lpos)); // 解析第一个空格之前的数字作为xy_ = stoi(in.substr(rpos));    // 解析最后一个空格之后的数字作为yif (lpos + 2 != rpos)return false;   // 如果两个空格之间不是一个字符的间隔,解析失败op_ = in[lpos + 1]; // 解析两个空格之间的字符作为操作符return true;        // 解析成功}public:int x_;   // 请求中的参数xint y_;   // 请求中的参数ychar op_; // 请求中的操作符
};
  1. request(const int &x, const int &y, const char op):构造函数,接受三个参数,分别为整数 x、整数 y 和字符 op,用于初始化请求对象的成员变量。

  2. request():默认构造函数,没有参数,用于创建一个空的请求对象。

  3. bool Serialize(string *out):序列化函数,将请求对象序列化为格式为 “x + y” 的字符串。其中,xy 分别代表请求中的参数,op 代表请求中的操作符。该函数将序列化结果存储在指针
    out 指向的字符串中,并返回 true 表示序列化成功。

  4. bool Deserialize(const string &in):反序列化函数,将字符串反序列化为请求对象。该函数接受一个字符串 in 作为参数,该字符串应该是由 Serialize
    函数生成的格式化字符串。函数会尝试从字符串中解析出参数 xy 和操作符
    op,并将其存储到请求对象的对应成员变量中。如果解析成功,则返回 true,否则返回 false

3. JSON与网络通信

在网络通信中,JSON(JavaScript Object Notation)作为一种通用的数据交换格式,经常被用来进行序列化和反序列化操作。它简单易懂的格式使得数据在网络上传输更加方便,并且能够被多种编程语言支持和解析。

  1. JSON的特点
    轻量级JSON 是一种轻量级的数据交换格式,对于数据量较小的情况下,其格式简洁明了,不会增加太多的网络负担。
    易读性JSON 使用键值对的形式表示数据,结构清晰,易于人类阅读和编写。
    可扩展性:JSON 支持嵌套结构,可以构建复杂的数据格式,并且支持数组等数据类型,使得它在不同场景下都能发挥作用。

  2. JSON与序列化、反序列化
    在网络通信中,序列化和反序列化是将数据转换为网络传输所需的格式和从网络接收的数据转换为程序可识别的格式的过程。JSON 与序列化、反序列化密切相关:

序列化 (Serialization)
Serialize 方法中,我们将 request 对象的成员变量 x_y_op_ 序列化为 JSON 格式的字符串。我们使用了 Json::Value 对象来表示 JSON 数据,然后将 x_y_op_ 分别赋值给 JSON 对象的相应字段。最后,我们使用 Json::StyledWriterJSON 对象转换为格式化后的 JSON 字符串,并将其存储在传入的 out 字符串中。

// 将请求对象序列化为 JSON 格式的字符串
bool request::Serialize(std::string *out) {// 创建一个 Json::Value 对象,用于存储 JSON 数据Json::Value s;// 创建 JSON 对象并填充数据s["x"] = x_;   // 将 x_ 存储为键为 "x" 的字段s["y"] = y_;   // 将 y_ 存储为键为 "y" 的字段s["op"] = op_; // 将 op_ 存储为键为 "op" 的字段// 使用 Json::StyledWriter 将 JSON 对象转换为格式化后的 JSON 字符串Json::StyledWriter w;*out = w.write(s); // 将转换后的 JSON 字符串存储到 out 中return true; // 序列化成功
}

反序列化 (Deserialization)
Deserialize 方法中,我们从传入的 JSON 格式的字符串中解析出 x_y_op_ 的值,并赋值给 request 对象的相应成员变量。我们使用了 Json::Value 对象来解析 JSON 数据,并使用 Json::Reader 对象来解析 JSON 字符串。然后,我们从 Json::Value 对象中提取出 xyop 字段的值,并分别赋值给 request 对象的成员变量。

// 将 JSON 格式的字符串反序列化为请求对象
bool request::Deserialize(const std::string &in) {// 创建一个 Json::Value 对象,用于存储 JSON 数据Json::Value s;// 创建一个 Json::Reader 对象,用于解析 JSON 数据Json::Reader r;// 使用 Json::Reader 解析传入的 JSON 字符串并存储到 Json::Value 对象 s 中r.parse(in, s);// 从 Json::Value 对象中提取字段的值并赋值给请求对象的成员变量x_ = s["x"].asInt();          // 获取键为 "x" 的字段值并转换为整数,赋值给 x_y_ = s["y"].asInt();          // 获取键为 "y" 的字段值并转换为整数,赋值给 y_op_ = s["op"].asString()[0]; // 获取键为 "op" 的字段值的第一个字符,赋值给 op_ (假设 op 是单个字符)return true; // 反序列化成功
}

序列化:将对象或数据结构转换为 JSON 格式的字符串,以便在网络上传输。序列化过程需要将对象的各个属性转换为 JSON 对象的键值对,并将其按照 JSON 的格式进行组织。
反序列化:将接收到的 JSON 格式的字符串转换为程序可识别的对象或数据结构。反序列化过程需要解析 JSON 字符串,提取其中的数据,并将其转换为程序内部可处理的格式。

完整代码:https://gitee.com/yua-lian/learning ( TCP 网络编程 序列化、反序列化)


http://www.ppmy.cn/news/1394856.html

相关文章

Python 如何设置和读取 config.ini 文件

当你开始编写Python应用程序时,通常需要一种方法来配置应用程序的设置,如数据库连接信息、API密钥等。使用配置文件是一种常见的方法,而INI文件是一种简单而常见的配置文件格式。在本文中,我将介绍如何使用Python设置和读取INI格式…

HPE DL580 Gen9到家了,成功开机!

正文共:1234 字 17 图,预估阅读时间:1 分钟 现在这个时代,学点新知识的成本实在是太高了。因为单宽的GPU性能较低、显存较小,还得上双宽的GPU。具体来说,Tesla M4的架构老了一些,只有4 GB显存&a…

二叉树试题解析

一、单项选择题 01.下列关于二叉树的说法中,正确的是( C ). A.度为2的有序树就是二叉树 B.含有n个结点的二叉树的高度为 C.在完全二叉树中,若一个结点没有左孩子,则它必是叶结点 D.含有n个结点的完全二叉树的高度为解析:A 二叉树…

jetcache 2级缓存模式实现批量清除

需求 希望能够实现清理指定对象缓存的方法,例如缓存了User表,当User表巨大时,通过id全量去清理不现实,耗费资源也巨大。因此需要能够支持清理指定本地和远程缓存的批量方法。 分析 查看jetcache生成的cache接口,并没…

ubuntu20.04 编译瑞芯微rv1126问题集锦

1、camera_engine_rkisp is in the dependency chain of app_demo that has added it to its _DEPENDENCIES variable without selecting it or depending on it from Config.in. Stop. 解决方案: 注释:rv1126/buildroot/package/rockchip/app_demo/Con…

⾃定义类型:联合和枚举

目录 1. 联合体 1.1 联合体类型的声明 1.2 联合体的特点 1.3 相同成员的结构体和联合体对⽐ 1.4 联合体⼤⼩的计算 1.5联合的⼀个练习 2. 枚举类型 2.1 枚举类型的声明 2.2 枚举类型的优点 2.3 枚举类型的使⽤ 1. 联合体 1.1 联合体类型的声明 像结构体⼀样&#xff…

Leetcode 3091. Apply Operations to Make Sum of Array Greater Than or Equal to k

Leetcode 3091. Apply Operations to Make Sum of Array Greater Than or Equal to k 1. 解题思路2. 代码实现 题目链接:3091. Apply Operations to Make Sum of Array Greater Than or Equal to k 1. 解题思路 这一题的话本质上算是一个数学题,具体就…

Matlab从入门到精通课程

教程介绍 MATLAB是美国MathWorks公司出品的商业数学软件,用于数据分析、无线通信、深度学习、图像处理与计算机视觉、信号处理、量化金融与风险管理、机器人,控制系统等领域。 学习地址 链接:https://pan.baidu.com/s/1PxGarBwQusMzwPVqcE…