网站分析报告范文,四川省省建设厅网站,如何查询网站使用什么框架做的,team talk wordpress目录
序言
序列化是什么#xff1f;
为什么要序列化#xff1f;
--什么是大小端存储#xff1f;
内存地址与字节分布
什么#xff1f;什么是网络字节序#xff1f;
拓展#xff1a;
一、JSON 序列化为何天然规避字节序#xff1f;
核心原理#xff1a;字符…目录
序言
序列化是什么
为什么要序列化
--什么是大小端存储
内存地址与字节分布
什么什么是网络字节序
拓展
一、JSON 序列化为何天然规避字节序
核心原理字符流无多字节序问题
二、二进制序列化的大小端困境与网络字节序
1. 二进制序列化的 端序隐患
2. 网络字节序二进制数据的 统一语言
三、htonl 与序列化的本质区别简单数据 vs 结构化数据
1. 简单数据如端口号的处理
2. 结构体的序列化需求
四、序列化的两大核心目的总结
1. 消除平台差异大小端、数据类型
2. 结构化标识字段解析规则
五、类比理解序列化如同 数据的快递单
六、实践建议不同场景的序列化策略 序言
我们之前已经学过了序列化例如Json而且我们知道TCP面向字节流的数据在网络中传输需要进行序列化以及了解到了网络字节序等关键词但是他们之间究竟有什么关系呢似乎我们都有些许疑惑我们来梳理一下
序列化是什么
序列化其实就是将我们代码中的结构化的数据转化成另外一种格式比如Json序列化我们知道转化到Json格式的key-value格式的数据结构其类型其实是字符串。
当然不止这一种序列化方式我们还可以序列化成其他的格式例如二进制、XML格式等而不同的格式其特点也是不同的后序在场景中需要的操作也是不同的。(网络字节序/大小端存储的问题)
好现在我们知道了什么是序列化序列化就是将结构化的对象转化为另外一种特殊的格式比如Json串二进制XML
但其实这里还可以分类其中Json和XML都属于是文本类型的数据格式
这是AI给出的几种序列化目标对象总结的很好。
那么接下来我们就要探讨为什么要进行序列化了也就是序列化要解决的是什么问题
为什么要序列化
---解决发送方和接收方在网络中对数据存储顺序的认识不一致的问题。
也就是大小端存储的问题。
--什么是大小端存储
我们先来看一下常见的几种数据类型比如charint,double等其中char字符是只有一个字节而其他的类型是多字节类型数据的存储顺序可分为两种一个是小端存储一个是大端存储。
内存地址与字节分布
假设整数存储在内存地址 0x1000 开始的 4 字节空间
地址大端序存储高位在前小端序存储低位在前0x10000x12最高位字节0x78最低位字节0x10010x340x560x10020x560x340x10030x78最低位字节0x12最高位字节
如果网络通信中发送方数据是大端存储而接收方是小端存储那么就会造成双方解析错误
所以序列化的第一个目的就是解决不同平台的大小端存储的差异
如果我们将数据序列化成Json字符串那么是不是就不存在字节序的问题了因为字符串是字符组成的每一个字符一个字节存储一个数据没有字节顺序。
但是如果序列化成二进制格式而二进制格式的数据仍然有大小端存储的区别所以序列化后还需要进行转化成网络字节序。
什么什么是网络字节序
咬文嚼字网络字节序就是在数据在网络中的存储顺序其实还是大小端存储的问题只不过网络字节序指的是规定好的字节序TCP协议是面向字节流的其规定的网络字节序就是大端存储也就是如果使用TCP协议进行通信那么就必须要将数据转化为网络字节序才可以正确的在网络中传输。 好回到刚才的问题我们说到序列化成二进制格式的数据依旧存在大小端存储的问题那么就需要将序列化的数据转化成网络字节序。这没问题。
但是我有个问题我们知道转化成网络字节序可以使用接口htonl但是我们之前写socket服务端的时候端口号也需要转化为网络字节序可是确实直接将变量作为实参传递这不是没有进行序列化也可以吗
NO! 这里的区别在于端口号要么是int要么是char[]没有结构化的数据何谈序列化
但是如果对象是一个结构体那个是包含了几个多个字节的类型对象的在场景中序列化的目的不再是解决大小端存储的差异性问题了而是保证接收方可以正确的识别那几个字节的数据是哪个对象的
所以这就是序列化的第二个目的---保证接收方正确识别和解析结构化的对象
如果传递的是结构体类型的数据时如果不是序列化成文本类型(字符串)
拓展 一、JSON 序列化为何天然规避字节序
核心原理字符流无多字节序问题 数据表示形式 JSON 将数值转为字符串如1234→1234每个字符按编码如 UTF-8转为单字节或多字节字符编码。 例数字1234在 JSON 中是字符串1234存储为 UTF-8 字符流0x31 0x32 0x33 0x34每个字节独立表示字符无多字节数据的顺序问题。 跨平台一致性 接收方按字符串解析后再转为数值无论发送方是大端还是小端平台结果一致。
二、二进制序列化的大小端困境与网络字节序
1. 二进制序列化的 端序隐患 问题本质 二进制序列化直接存储数据的内存二进制表示不同平台的字节序差异会导致解析错误。 例小端平台序列化int32 0x12345678为字节流0x78 0x56 0x34 0x12大端平台解析为0x78563412与原值完全不同。
2. 网络字节序二进制数据的 统一语言 定义 网络字节序即大端序是 TCP/IP 协议强制要求的传输格式要求所有多字节数据在网络传输时转为大端。 与序列化的配合 发送方序列化二进制数据时对每个多字节整数调用htonl()/htons()转大端 接收方用ntohl()/ntohs()转回本地字节序。
三、htonl 与序列化的本质区别简单数据 vs 结构化数据
1. 简单数据如端口号的处理 为何无需序列化 端口号2 字节 int是单一数据类型通信双方提前约定 这是一个端口号需用大端解析本质是 极简序列化隐含结构编码单一 int 类型无其他字段。 代码示例 uint16_t port 8080; // 本地端口小端存储为0x80 0x20uint16_t net_port htons(port); // 转大端为0x20 0x800x20808320send(sockfd, net_port, 2, 0);
2. 结构体的序列化需求 必须序列化的原因 结构体包含多个字段需解决 字段身份绑定如何区分int age和int score的字节流 解析顺序先读age还是score 类型标识如何区分int和float的字节流。 示例结构体序列化流程 struct User {char name[20]; // 字符串int age; // 年龄float height; // 身高};// 序列化伪代码void serialize(User* u, uint8_t* buf) {// 1. 写入name长度解决字段长度问题uint32_t name_len strlen(u-name);uint32_t net_name_len htonl(name_len);memcpy(buf, net_name_len, 4);// 2. 写入name内容memcpy(buf4, u-name, name_len);// 3. 写入age转大端uint32_t net_age htonl(u-age);memcpy(buf4name_len, net_age, 4);// 4. 写入height转大端需按float格式处理// ...省略float字节序转换}
四、序列化的两大核心目的总结
1. 消除平台差异大小端、数据类型 处理对象多字节数值int、float 等的字节序统一。 技术手段通过htonl转网络字节序或文本序列化规避端序。
2. 结构化标识字段解析规则 处理对象结构体、对象等复杂数据结构。 技术手段 约定字段顺序如先name后age 添加字段标签如 Protobuf 的Tag 声明字段类型如 4 字节表示 int8 字节表示 double。
五、类比理解序列化如同 数据的快递单 大小端处理相当于要求快递包裹内的多件物品多字节数据必须按从大到小排列大端 结构化标识快递单上的 收件人姓名 地址 电话 等字段确保快递员接收方能按规则分拣包裹解析数据。 关键若没有快递单序列化规则即使包裹内物品排列整齐处理了大小端也无法知道该送给谁字段映射。
六、实践建议不同场景的序列化策略
场景序列化策略示例代码简单数值传输直接转网络字节序极简序列化net_port htons(local_port)结构体跨平台通信二进制序列化 网络字节序Protobuf 生成代码 htonl转换异构系统集成文本序列化JSON/XMLjson.dumps(obj) → 字符串传输
通过将技术概念与生活场景类比可以更直观地理解序列化的本质 —— 它不仅是字节序的转换更是数据结构的跨平台 翻译规则。在实际开发中根据数据复杂度和性能需求选择合适的序列化方式是保障系统稳定性的关键。