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

时间:2024-03-26 19:01:39

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

  • 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)); // 解析第一个空格之前的数字作为x
        y_ = stoi(in.substr(rpos));    // 解析最后一个空格之后的数字作为y
        if (lpos + 2 != rpos)
            return false;   // 如果两个空格之间不是一个字符的间隔,解析失败
        op_ = in[lpos + 1]; // 解析两个空格之间的字符作为操作符
        return true;        // 解析成功
    }

public:
    int x_;   // 请求中的参数x
    int y_;   // 请求中的参数y
    char 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 网络编程 序列化、反序列化)