Linux 应用层自定义协议与序列化

文章目录

一、应用层

1、协议

  • 协议本质是一种约定。
  • 协议就是双方约定好的结构化数据。

2、序列化 && 反序列化

在用户在网络中发送的信息类型不都是字符串,有可能是整型,浮点数,自定义类型等等,将不同的类型通过网络发送给另外一个客户端,然后进行识别明显是比较困难的,为了解决这种事情,我们把发送的消息进行序列化和反序列化来对信息进行封装和解封。

3、通过Json库进行数据的序列化 && 反序列化

Json::Value类

  • operator[]:通过键名或索引访问JSON对象中的元素。
  • append:向JSON数组中添加元素。
  • asString、asInt、asFloat、asBool等:将Json::Value对象转换为不同的数据类型。
  • type():获取Json::Value对象的类型。
cpp 复制代码
    // 创建一个Json::Value 对象
    Json::Value root;

    // 通过键值访问Json对象元素,如果没有键值对应的元素则新建
    root["name"] = "zhangsan";
    root["age"] = 18;
    root["year" ] = 2024;

    // 向数组中添加键值对
    // 创建一个Json::Value对象,并初始化为数组类型
    Json::Value root(Json::arrayValue);
    // 使用append方法向数组中添加元素
    root.append("Hello"); // 添加一个字符串
    root.append(123);     // 添加一个整数
    root.append(45.67);   // 添加一个浮点数

    // 将Json::Value对象转换为不同的数据类型
    // asString、asInt、asFloat、asBool等
    int age = root["age"].asInt();
    std::string name = root["name"].asString();
    // 获取Json::Value对象的类型
    // Null:表示JSON中的null值。
    // String:表示JSON中的字符串值。
    // Number:表示JSON中的数字值,这通常包括整数和浮点数。不过,在某些实现中,可能会进一步区分整数(Int)和浮点数(Float或Double)。
    // Boolean:表示JSON中的布尔值(true或false)。
    // Array:表示JSON中的数组,数组可以包含多个JSON值,这些值的类型可以不同。
    // Object:表示JSON中的对象,对象由键值对组成,其中键是字符串,值是任意的JSON值。
    // ...
    Json::ValueType type = root.type();
    
    // 输出,测试 
    Json::FastWriter writer;
    std::string str = writer.write(root);
    std::cout << str << std::endl;

Json::Reader类

用于将JSON格式的字符串解析为Json::Value对象。

  • parse:解析JSON字符串,并将其存储在Json::Value对象中。
cpp 复制代码
// JSON格式的字符串
    std::string jsonStr = R"({"name": "John Doe", "age": 30, "is_student": false, "scores": [90, 85, 95]})";

    // 创建一个Json::Value对象来存储解析后的JSON数据
    Json::Value root;

    // 创建一个Json::Reader对象来解析JSON字符串
    Json::Reader reader;

    // 使用parse方法解析JSON字符串
    bool parsingSuccessful = reader.parse(jsonStr, root);

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

    // 解析成功后,可以使用root对象来访问JSON数据
    std::string name = root["name"].asString();
    int age = root["age"].asInt();
    bool isStudent = root["is_student"].asBool();

    // 访问数组中的元素
    Json::Value scores = root["scores"];
    for (int i = 0; i < scores.size(); ++i)
    {
        std::cout << "Score " << i + 1 << ": " << scores[i].asInt() << std::endl;
    }

    // 输出一些基本信息
    std::cout << "Name: " << name << std::endl;
    std::cout << "Age: " << age << std::endl;
    std::cout << "Is Student: " << std::boolalpha << isStudent << std::endl;

Json::Writer类

  • 功能:Json::Writer是一个抽象基类,用于将Json::Value对象序列化为JSON格式的字符串。通常不会直接使用,而是使用其子类如Json::StyledWriter或Json::FastWriter。
  • 子类 :
    • Json::StyledWriter:生成格式化的JSON字符串,易于阅读。
    • Json::FastWriter:生成紧凑的JSON字符串,没有额外的空格和换行符。
cpp 复制代码
    Json::Value root;
    root["name"] = "zhangsan";
    root["age"] = 18;
    root["year"] = 2024;

    Json::FastWriter fast_write;
    Json::StyledWriter styledwriter;

    std::string str1 = fast_write.write(root);
    std::cout << str1 << std::endl;
    std::cout << "------------------------------" << std::endl;
    std::string str2 = styledwriter.write(root);
    std::cout << str2 << std::endl;

二、为什么read、write、recv、send和Tcp支持全双工?

  • 一个文件描述符fd,代表一个连接。一个连接,有两个缓冲区,发送缓冲区和接收缓冲区。
  • read、write、send、recv**本质都是拷贝函数**。

发数据的本质:

从发送方的发送缓冲区把数据通过协议栈和网络拷贝给接收方的接收缓冲区。

tcp支持全双工通信的原因:

有两个缓冲区,读写不受到冲突。

(传输控制协议!什么时候发?发多少?出错了怎么办?均有tcp决定。)

为什么IO函数要阻塞?

本质就是在维护同步关系!

其他:

  • 网络层、传输层 属于 os。
  • 面向字节流:客户端发的,不一定全部是服务器收的。--- 也就是说客户端可能发送的不是一个完整报文。

因为面向字节流,可能读取不了一个完成的请求,那如何保证在主机中保证处理的是一个完整的请求?

  • 网络层、传输层 属于 os。
  • 面向字节流:客户端发的,不一定全部是服务器收的。--- 也就是说客户端可能发送的不是一个完整报文。

因为面向字节流,可能读取不了一个完成的请求,那如何保证在主机中保证处理的是一个完整的请求?

手动分割完整的报文。

相关推荐
AR-26710-1 小时前
Linux Day33——定时任务+lvm
linux·运维
墨痕诉清风2 小时前
SSRF漏洞实战记录+OSS桶命令执行+MCP漏洞
linux·服务器·数据库
byte轻骑兵2 小时前
实战 4:BlueZ 源码中添加自定义设备过滤规则
linux·物联网·bluez·电脑蓝牙·嵌入式蓝牙
瓦瓦gogo3 小时前
从一个 TypeScript 函数开始理解 MCP 协议
linux·ubuntu·typescript
鱼听禅4 小时前
Ubuntu安装YOLOv8进行菌落识别训练
linux·python·yolo·ubuntu
测试界的小码农5 小时前
【Linux 命令实战(04):文件内容查看,掌握 cat、less、head、tail】
linux·服务器·less
CodeYp20195 小时前
第13讲:HTTPS 协议原理
linux·https
一条破秋裤6 小时前
【1112】Linux中断【整理】
linux·运维·服务器
CodeYp20198 小时前
第14讲:传输层协议 UDP
linux·udp
北京迅为8 小时前
案例分享 | RK182X算力卡:多路视频VLM监控,四路画面AI同时看懂,一句人话说清现场
linux·人工智能·嵌入式·rk3588·算力卡·rk182x