网络通信应用层协议-序列化与反序列化

目录

1、序列化与反序列化概念

2、正、反序列化的目的

3、添加报头的目的 

4、实现正、反序列化思路

5、代码实现

6、添加报头、去除报头 

结语 


前言:

        在进行网络通信时,应用层协议是需要程序员手动定制的,序列化与反序列化是对协议进行字符串形式的转换。应用层协议表示发送端和接收端共同遵守的规则,依照这个规则,通信的双方才能够分析出传输数据的真正含义,只有理解了数据的真正含义,才能对数据进行处理,因此应用层协议在网络通信中非常重要。传输层协议为TPC\UDP,网络层协议为ipv4\ipv6,这些协议都是设置好的,而应用层协议需要程序员手动实现,传输应用层协议需要进行序列化与反序列化。 

1、序列化与反序列化概念

         序列化与反序列化是发送端和接收端对网络中传输数据的处理,是一种对传输数据的解释行为,通信双方制定好协议后,发送端需要将协议化的数据通过序列化传给接收端,而接收端拿到数据后需要对其进行反序列化以拿到协议的对应内容,具体示意图如下:

        如上图所示,序列化和反序列化实际上就是结构体->字符串,字符串->结构体的过程。

2、正、反序列化的目的

        反序列化的目的好理解,因为数据在传输前进行了正序列化,此时数据已经被“修饰”了,那么接收端必须采用同样的方式去掉“修饰”才能拿到有效数据,把这种行为叫做反序列化。那么为什么在传输数据前要将协议进行序列化呢?

        答:因为结构体类型在不同平台上的大小、存放形式不一样,因此不能直接将结构体传输给对方,并且结构体难以用字节流的形式在网络上传输。所以要进行序列化将其转换成字符串的形式传递。

3、添加报头的目的 

        上图中对协议内容进行添加报头,该行为的目的是为了接收方可以更好的解析序列化内容,还能够给在报头中进行数据加密,提供安全性。最主要的是若传输过程中出现数据丢失,则可以通过报头里的信息来判断是否发生数据丢失, 提供了数据在传输过程中的完整性。另外,还可以提供此次数据的版本号等等。

4、实现正、反序列化思路

        我们可以实现一个简单的计算机类,因为正反序列化是要在网络传输的过程中发挥作用的,为了能够更简单的描绘出正反序列化,所以我们在一个main函数中将整个过程模拟出来,方便理解。

        实现正、反序列化的思路:首先通信双方必须遵守同一个协议,即有同一个结构体类型,发送端发送的数据是由该结构体的成员变量进行序列化后再发送的,接收端拿到数据后先进行反序列化,然后添加到协议(结构体)里,此时说明接收端已经具备了处理数据的能力。如下图:

5、代码实现

        计算机类如下:

#pragma once#include <iostream>
#include <string>
//用“ ”和“\n”表示协议的具体规定
const std::string blank_space_sep = " ";
const std::string protocol_sep = "\n";class Request
{
public:Request(int data1, int data2, char oper) : x(data1), y(data2), op(oper){}Request(){}public:bool Serialize(std::string *out)//序列化{// struct => string, "x op y"//根据协议的规定进行序列化std::string s = std::to_string(x);s += blank_space_sep;s += op;s += blank_space_sep;s += std::to_string(y);*out = s;return true;}bool Deserialize(const std::string &in) //反序列化{//根据协议的规定拿到有效数据std::size_t left = in.find(blank_space_sep);if (left == std::string::npos)return false;std::string part_x = in.substr(0, left);std::size_t right = in.rfind(blank_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 yint x;int y;char op; // + - * / %
};

         模拟序列化与反序列化的过程如下:

#include "app1.hpp"
#include <unistd.h>int main(int argc, char *argv[])
{//模拟客户端序列化Request req(12364566, 43454356, '+');std::string s;req.Serialize(&s);std::cout << s <<std::endl;//模拟服务器反序列化Request temp;temp.Deserialize(s);temp.DebugPrint();return 0;
}

        运行结果:

6、添加报头、去除报头 

        添加报头的逻辑:将数据的长度作为报头的内容,并且用\n将报头内容与数据做分隔,这样接收端就可以根据第一个\n来拿到报头了。

        去除报头的逻辑:根据\n来拿到报头的内容,因为报头的内容是数据的长度,因此可以根据报头内容将数据从中取出。


         添加报头、去除报头的代码如下:

//添加报头:将数据长度作为报头内容,并用\n分隔开来
//(“len”\n"x op y"\n)
std::string Encode(std::string &content)
{std::string package = std::to_string(content.size());package += protocol_sep;package += content;package += protocol_sep;return package;
}
//根据报头内容以及\n,去掉报头,从而拿到数据本身
bool Decode(std::string &package, std::string *content)
{std::size_t pos = package.find(protocol_sep);if (pos == std::string::npos)//数据不完整,返回return false;std::string len_str = package.substr(0, pos);std::size_t len = std::stoi(len_str);std::size_t total_len = len_str.size() + len + 2;if (package.size() < total_len)//数据不完整,返回return false;*content = package.substr(pos + 1, len);// 走到此次说明数据正确被取出,因此package里的数据可以清空package.erase(0, total_len);return true;
}

        运行结果:

结语 

         以上就是关于网络通信应用层协议-序列化与反序列化的讲解,序列化与反序列化并不代码应用层协议本身,但是他与应用层协议密切相关,应用层协议是通信双方对传输的数据格式达成一致观念,而序列化与反序列化是进行数据传输的一种手段,他只一种行为。

        最后如果本文有遗漏或者有误的地方欢迎大家在评论区补充,谢谢大家!! 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://xiahunao.cn/news/3266587.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

vue3前端开发-小兔鲜项目-产品详情基础数据渲染

vue3前端开发-小兔鲜项目-产品详情基础数据渲染&#xff01;这一次内容比较多&#xff0c;我们分开写。第一步先完成详情页面的基础数据的渲染。然后再去做一下右侧的热门产品的列表内容。 第一步&#xff0c;还是老规矩&#xff0c;先准备好接口函数。方便我们的页面组件拿到对…

新版海螺影视主题模板M3.1全解密版本多功能苹果CMSv10后台自适应主题

苹果CMS2022新版海螺影视主题M3.1版本&#xff0c;这个主题我挺喜欢的&#xff0c;之前也有朋友给我提供过原版主题&#xff0c;一直想要破解但是后来找了几个SG11解密的大哥都表示解密需要大几百大洋&#xff0c;所以一直被搁置了。这个版本是完全解密的&#xff0c;无需SG11加…

Java Selenium WebDriver:代理设置与图像捕获

在网络爬虫和自动化测试领域&#xff0c;Selenium WebDriver 是一个非常流行的工具&#xff0c;它允许开发者模拟用户在浏览器中的操作。然而&#xff0c;出于安全或隐私的考虑&#xff0c;有时我们需要通过代理服务器来发送请求。本文将介绍如何在Java环境中使用Selenium WebD…

Docker(十一)-Docker运行nginx1.10容器实例

1.下载镜像 docker pull nginx:1.102.直接启动实例(目的&#xff1a;复制出配置文件) 2.1启动实例 docker run -d -p 80:80 --namenginx1.10 nginx:1.102.2将容器内文件拷贝到本地目录 docker cp nginx1.10:/etc/nginx /software/nginx/将/software/nginx/nginx目录改为/so…

通过强大的语义层增强现代数据湖

在现代数据湖架构中&#xff0c;语义层通过向数据添加有意义的上下文来发挥至关重要的作用&#xff0c;否则这些上下文会丢失。此层充当现代数据湖&#xff08;数据仓库和查询引擎&#xff09;处理层中未整理的原始数据与利用此数据的工具和应用程序之间的桥梁。此服务对 AI 特…

IOS微软语音转文本,lame压缩音频

在IOS开发中&#xff0c;用微软进行语音转文本操作&#xff0c;并将录音文件压缩后返回 项目中遇到了利用微软SDK进行实时录音转文本操作&#xff0c;如果操作失败&#xff0c;那么就利用原始音频文件通过网络请求操作&#xff0c;最终这份文件上传到阿里云保存&#xff0c;考…

Find My电子书|苹果Find My技术与电子书结合,智能防丢,全球定位

电子书是指将文字、图片、声音、影像等讯息内容数字化的出版物和植入或下载数字化文字、图片、声音、影像等讯息内容的集存储和显示终端于一体的手持阅读器。代表人们所阅读的数字化出版物&#xff0c;区别于以纸张为载体的传统出版物。电子书通过数码方式记录在以光、电、磁为…

PostgreSQL性能优化之体系结构

本文介绍 PostgreSQL 数据库的体系结构&#xff0c;包括实例结构&#xff08;进程与内存&#xff09;、存储结构&#xff08;物理与逻辑&#xff09;以及插件式存储引擎。 实例与数据库聚簇 PostgreSQL 使用典型的客户端/服务器&#xff08;Client/Server&#xff09;架构&am…

基于Intel x86+FPGA+AI工业整机,支持医疗CT扫描仪应用

众所周知&#xff0c;医学影像设备是医疗器械行业中最具发展潜力的细分领域之一&#xff0c;诸如CT扫描仪&#xff08;简称&#xff1a;CT&#xff09;便是医生用于多种疾病临床检查和诊治时的理想选择。 医疗CT扫描仪的发展潜力及难点 CT&#xff0c;即电子计算机X线断层扫描&…

计算机网络:构建联结的基础

目录 1. 网络拓扑结构 1.1 星型拓扑 1.2 环型拓扑 1.3 总线型拓扑 1.4 网状拓扑 2. 传输介质 2.1 双绞线 2.2 同轴电缆 2.3 光纤 2.4 无线电波 3. 协议栈模型 3.1 OSI模型 3.2 TCP/IP模型 4. 网络设备 4.1 交换机 4.2 路由器 4.3 网关 4.4 防火墙 5. IP地址…

2024年数字化社会、信息科学与风险管理研讨会(ICDIR 2024,9月20-22)

2024年数字化社会、信息科学与风险管理研讨会&#xff08;ICDIR 2024&#xff09;作为2024年人工智能与数字管理国际学术会议&#xff08;ICAIDM 2024&#xff09;的分论坛&#xff0c;将携手主会齐于2024年9月22-24日在中国江苏省南京市隆重召开。 会议旨在为从事数字化社会、…

DjangoRF实战-2-apps-users

1、用户模块 创建一个用户模块子应用&#xff0c;用来管理用户&#xff0c;和认证和授权。 1.1根目录创建apps&#xff0c; 为了使用方便&#xff0c;还需要再pycharm中设置一下资源路径&#xff0c;就可以自动提示 1.2注册子应用 1.3添加应用根目录到环境变量path python导…

Java---后端文件上传详解

袁门才俊志高远&#xff0c; 震古烁今意决然。 风采翩翩才情显&#xff0c; 雄姿英发立世间。 目录 一&#xff0c;简单案例演示 二&#xff0c;服务器本地存储 三&#xff0c;配置单个文件上传大小限制 一&#xff0c;简单案例演示 首先简单编写一个前端网页&#xff1a; &l…

vue3+openLayers点击标记事件

<template><!--地图--><div class"distributeMap" id"distributeMap"></div> </template> <script lang"ts" setup> import { onMounted, reactive } from "vue"; import { Feature, Map, View }…

C++中的依赖注入

目录 1.概述 2.构造函数注入 3.setter方法注入 4.接口注入 5.依赖注入框架 6.依赖注入容器 7.依赖注入框架的工作原理 8.依赖注入的优势 9.总结 1.概述 依赖注入是一种设计模式&#xff0c;它允许我们在不直接创建对象的情况下为对象提供其依赖项&#xff1b;它通过将…

模拟信号介绍

定义&#xff1a; 模拟信号是指用连续变化的物理量表示的信息&#xff0c;其信号的幅度、频率或相位随时间作连续变化&#xff0c;或在一段连续的时间间隔内&#xff0c;其代表信息的特征量可以在任意瞬间呈现为任意数值的信号。我们通常又把模拟信号称为连续信号&#xff0c;它…

Pytorch使用教学6-张量的分割与合并

在使用PyTorch时&#xff0c;对张量的分割与合并是不可避免的操作&#xff0c;本节就带大家深刻理解张量的分割与合并。 在开始之前&#xff0c;我们先对张量的维度进行深入理解&#xff1a; t2 torch.zeros((3, 4)) # tensor([[0., 0., 0., 0.], # [0., 0., 0., 0.…

java发送https请求支持tls1.3

说明&#xff1a;java 8_u201及以下版本不支持tls1.3协议发送。最直接的方法是升级到该版本之上。 另外&#xff1a;需要修改一下代码强行使用tls1.3协议。如果只修改代码&#xff0c;不升级java版本会报错找不到该协议。

【基于PSINS】UKF/SSUKF对比的MATLAB程序

UKF与SSUKF UKF是&#xff1a;无迹卡尔滤波 SSUKF是&#xff1a;简化超球面无迹卡尔曼滤波 UKF 相较于传统的KF算法&#xff0c;UKF能够更好地处理非线性系统&#xff0c;并且具有更高的估计精度。它适用于多种应用场景&#xff0c;如机器人定位导航、目标跟踪、信号处理等。…

【解决方案】华普微基于CMT2189D的低功耗广域网解决方案

一、方案概述 随着物联网的快速发展&#xff0c;对于无线通信的需求越来越高。传统的通信技术可能无法满足物联网设备的特殊要求&#xff0c;如低功耗、长距离覆盖和大规模连接。LPWAN技术应运而生&#xff0c;旨在为物联网设备提供低成本、低功耗的远距离通信解决方案。ZETA作…