SOME/IP 协议详解——序列化
文章目录
- 0. 概述
- 1.基本数据序列化
- 2.字符串序列化
- 2.1 字符串通用规则
- 2.2 固定长度字符串规则
- 2.3 动态长度字符串规则
- 3.结构体序列化
- 4. 带有标识符和可选成员的结构化数据类型
- 5. 数组
- 5.1 固定长度数组
- 5.2 动态长度数组
- 5.3 Enumeration(枚举)
- 5.4 Bitfield(位域)
- 5.5 Union/Variant(联合 / 变体)
- 总结
0. 概述
SOME/IP序列化分为四部分,基本数据序列化,字符串序列化,结构体序列化,数组序列化。
1.基本数据序列化
Type | Description | Size [bit] | Remark |
---|---|---|---|
boolean | TRUE/FALSE value | 8 | FALSE (0), TRUE (1) |
uint8 | unsigned Integer | 8 | |
uint16 | unsigned Integer | 16 | |
uint32 | unsigned Integer | 32 | |
sint8 | signed Integer | 8 | |
sint16 | signed Integer | 16 | |
sint32 | signed Integer | 32 | |
float32 | floating point number | 32 | IEEE 754 binary32 (Single Precision) |
float64 | floating point number | 64 | IEEE 754 binary64 (Double Precision) |
对于每个参数的字节序,是由配置来决定的(大小端顺序)。这就好比是给一群数字 “小朋友” 排队,不同的配置会让他们站成不同的顺序。
在对布尔值进行评估时,只看 uint8 中的最低位,其他位都被忽略。
这些基本数据类型在 SOME/IP 协议中就像是一个个小积木,通过不同的组合和排列,构建起了复杂的数据结构,支撑着整个协议的数据处理和传输功能。
2.字符串序列化
2.1 字符串通用规则
- 编码支持
- 支持不同的 Unicode 编码,包括 UTF - 8、UTF - 16BE 和 UTF - 16LE。
- 字符串终止
- UTF - 16LE 和 UTF - 16BE 字符串应以零字符(‘\0’)终止,且至少有两个 0x00 字节。
- 所有字符串应始终以字节顺序标记(BOM)开始,BOM 应包含在固定长度和动态长度字符串中,用于检测编码。
2.2 固定长度字符串规则
- 字符串终止
- 固定长度字符串也应以 ‘\0’ 字符终止,且字符串长度(包括 ‘\0’ 字节)在数据类型定义中指定,未使用空间用 ‘\0’ 填充,BOM 包含在长度内。
- 长度检查
- 如果固定长度字符串长于预期,反序列化应停止,消息视为格式错误。
- 如果固定长度字符串短于预期但正确以 ‘\0’ 终止,可接受。
- 如果固定长度字符串短于预期且未正确以 ‘\0’ 终止,反序列化应停止,消息视为格式错误。
2.3 动态长度字符串规则
- 长度字段
- 动态长度字符串应以长度字段开始,长度以字节为单位测量,长度字段在 BOM 之前,BOM 包含在长度内,字符串以 ‘\0’ 终止,字符串(包括 ‘\0’ 终止)的最大字节数由数据类型定义得出。
- 长度定义
- 动态长度字符串的长度字段有 8、16 或 32 位可选,由接口规范决定,未指定时默认 32 位。长度字段的值不包括长度字段本身。
- 如果动态长度字符串长于预期,反序列化应停止,消息视为格式错误。
- 替代传输方式
- 除了将应用程序字符串作为带有 BOM 和 ‘\0’ 终止的 SOME/IP 字符串传输外,还可将其作为普通动态长度数组传输(不带 BOM 和 ‘\0’ 终止),但应用程序需自行处理字符串,如编码转换。
概括而言:
定长字符串格式【BOM】【data】【‘\0’】
变长字符串格式【length】【BOM】【data】【‘\0’】
lenth大小默认为4byte,包含BOM,data和结束符的长度总和。
3.结构体序列化
- 总体原则
- 结构体序列化要依循内存布局,像按图施工一样逐个参数序列化到缓冲区,且要考虑内存对齐。
- 示例说明
以几个结构体及其内部成员(如 Struct_1 包含 uint32 a 和 float32 b [2] 等)展示序列化过程,如同按盒子内物品摆放顺序处理。 - 关键规则
- 填充数据:不会自动插入无用填充数据,保证数据紧凑。
- 长度字段:可配置插入 8、16 或 32 位长度字段来标识结构体传输字节数,长度不包含长度字段自身。
- 长度检查处理:接收长度大于定义时只按定义处理,多余跳过;长度小于且无法补全缺失数据时反序列化中止,视为格式错误。
- 序列化顺序:按深度优先遍历顺序进行序列化,确保成员处理无遗漏或重复。
4. 带有标识符和可选成员的结构化数据类型
-
总体目的
- 为了实现更好的前向和后向兼容性,在结构体成员或方法参数前可添加额外的数据标识符(Data ID)。接收方可以通过这些标识符跳过未知成员或参数,保证系统在处理新旧数据时的兼容性。
-
标识符规则
- 唯一性:数据标识符在一个 struct 的直接成员或方法的参数中必须唯一,但不需要在不同 struct 或方法之间保持唯一。
- 配置一致性:对于 struct 同一层级的所有成员,要么全部定义数据标识符,要么全部不定义;对于方法的所有参数,也是如此。
-
数据类型编码
- 除了数据标识符,还使用 “线类型(wire type)” 来编码成员的数据类型,两者共同组成 “标签(tag)”。
- 标签结构:标签长度为两个字节,其布局包含多个部分,包括保留位、线类型、数据标识符等。例如,保留位在第 7 位,线类型在第 6 - 4 位,数据标识符在第 3 - 0 位和第二个字节的全部 8 位。
-
不同数据类型的序列化规则
- 基本数据类型:如果序列化的成员或参数是基本数据类型(线类型 0 - 3)且配置了数据标识符,标签应直接插入在成员或参数前面,并且不插入长度字段。
- 复杂数据类型:如果是复杂数据类型(线类型 4 - 7)且配置了数据标识符,标签应插入在长度字段前面,并且必须插入长度字段。
-
长度字段相关规则
- 长度字段始终包含到 struct 中下一个标签的长度。对于 struct、动态长度字符串、动态长度数组、联合类型等,都有相应的长度字段规则,且这些类型的长度字段大小在配置中应大于 0,并且通常应配置为相同大小,以便在处理未知成员或参数时,接收方能够根据统一的规则来解析数据。
-
可选成员处理
- 序列化器在序列化时,如果可选成员被标记为不可用,不应将其包含在序列化字节流中;反序列化器在反序列化时,应忽略字节流中不存在的可选成员。
-
未知数据处理
- 如果反序列化器读取到未知的数据标识符,它应根据线类型和长度字段的信息跳过未知的成员或参数;如果在字节流中找不到必需的(非可选)成员或参数,反序列化应中止,并将消息视为格式错误。
-
接口版本与序列化兼容性
- 如果对现有服务接口引入带标签的序列化,而之前未使用标签,应增加主要接口版本来指示这一变化。
-
带有标签的序列化示例
5. 数组
5.1 固定长度数组
-
长度定义
- 固定长度数组的长度由数据类型定义确定。可以将其视为相同类型元素的重复排列。
- 例如,一维固定长度数组携带指定数量(n)的相同类型元素,其布局按照顺序依次排列,元素大小乘以元素数量就是数组占用的空间大小。
- 多维固定长度数组的序列化遵循编程语言中的内存布局(行主序)。
-
长度处理与错误情况
- 如果接收到的固定长度数组长度大于预期(根据数据类型定义),只解释指定数量的元素,多余字节根据长度字段跳过。
- 如果长度小于预期且接收方无法提供缺失数据的替代值,反序列化将中止,消息视为格式错误。
5.2 动态长度数组
-
布局与长度字段
- 动态长度数组的布局基于固定长度数组,可以在数组开头使用可选的长度字段来指定数组字节长度。
- 长度字段长度可以是 0、8 位、16 位或 32 位,由配置决定。当长度字段设置为 0 位时,数组元素数量固定,此时相当于固定长度数组。
-长度不包括长度字段本身大小。
-
多维数组特点
-
在多维动态长度数组中,每个不同维度的子数组都有自己的长度字段。
-
如果需要静态分配缓冲区大小,数据类型定义应指定每个维度的最大长度。
-
当测量字节长度时,复杂多维数组在反序列化时可以跳过。
-
SOME/IP 支持同一维度中列和行的不同长度,每个动态长度数组前都需要有长度指示。
-
-
长度处理与错误情况
- 如果动态长度数组长度大于预期,只解释指定数量的元素,多余字节根据长度字段跳过。
5.3 Enumeration(枚举)
- 枚举在 SOME/IP 中不作为独立类型考虑,而是被当作无符号整数数据类型传输。
5.4 Bitfield(位域)
- 位域应作为无符号数据类型(uint8/uint16/uint32)传输,数据类型定义可以指定每个位的名称和值。
5.5 Union/Variant(联合 / 变体)
-
联合用于在网络上传输具有不同数据类型的可选数据,由长度字段、类型选择器和有效负载组成。
-
长度字段定义数据和填充字节的大小(不包括长度字段和类型字段本身),类型字段指定数据类型,有效负载根据类型字段进行序列化。
-
长度字段长度由配置决定,可以是 32 位、16 位、8 位或 0 位,当长度字段为 0 位时,联合中的所有类型必须长度相同。
-
类型字段的值由配置为每个联合单独定义,其中 0 值保留用于空类型(表示空联合),并且是否允许空联合也由配置决定。
总结
整体来说,SOME/IP的序列化和反序列化比较死板,不够灵活。
相关文章:

SOME/IP 协议详解——序列化
文章目录 0. 概述1.基本数据序列化2.字符串序列化2.1 字符串通用规则2.2 固定长度字符串规则2.3 动态长度字符串规则 3.结构体序列化4. 带有标识符和可选成员的结构化数据类型5. 数组5.1 固定长度数组5.2 动态长度数组5.3 Enumeration(枚举)5.4 Bitfield…...

三、GIT与Github推送(上传)和克隆(下载)
GIT与Github推送(上传)和克隆(下载) 一、配置好SSH二、在Github创建仓库三、git克隆(下载)文件四、git推送(上传)文件到远程仓库 一、配置好SSH Git与Github上传和下载时需要使用到…...
18.2、网络安全评测技术与攻击
目录 网络安全测评技术与工具网络安全测评质量管理和标准 网络安全测评技术与工具 漏洞扫描技术可以用于测评,测评你安不安全,也可以用来风险评估安不安全,风险大不大 漏洞扫描包含网络安全漏洞扫描、主机安全漏洞扫描,还有数据…...

在 ArcGIS Pro/GeoScene Pro 中设计专题地图的符号系统
原始 按颜色对面进行符号化 打开符号系统 选择主符号系统 选择字段及其计算方式 更改临界值</...

CSS2笔记
一、CSS基础 1.CSS简介 2.CSS的编写位置 2.1 行内样式 2.2 内部样式 2.3 外部样式 3.样式表的优先级 4.CSS语法规范 5.CSS代码风格 二、CSS选择器 1.CSS基本选择器 通配选择器元素选择器类选择器id选择器 1.1 通配选择器 1.2 元素选择器 1.3 类选择器 1.4 ID选择器 1.5 基…...
移动端如何实现上拉加载
一、理解上拉加载的原理 上拉加载是一种在移动端很常见的交互方式,其原理是当用户在页面上向上滑动(即滚动条接近底部)时,触发一个加载更多数据的操作。这通常涉及到对滚动事件的监听以及判断滚动位置是否达到了触发加载的阈值。…...

【mysql】linux安装mysql客户端
参考文章: MySQL系列之如何在Linux只安装客户端 linux下安装mysql客户端client MySQL Community Downloads 查看linux版本方法: lsb_release -a cat /proc/version下载文件: rpm -ivh mysql-community-*可以删除错误的包: RP…...

YOLOv5部署到web端(flask+js简单易懂)
文章目录 前言最终实现效果图后端实现 主界面检测函数检测结果显示 前端实现 主界面(index.html)显示图片界面 总结 前言 最近,老板让写一个程序把yolov5检测模型部署到web端,在网页直接进行目标检测。经过1个星期的努力,终于实…...
【机器学习】深度学习(DNN)
文章目录 1. 神经网络结构2. 训练步骤3. 反向传播4. 为什么深,而不是宽(模块化)5. 初始化参数能否全为0? 1. 神经网络结构 输入层隐藏层:用于特征转换输出层:用于分类技巧:将网络中的参数写成矩…...

12.30-1-5学习周报
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 文章链接摘要Abstract一、方法介绍1.HAT-CIR2.Horde3.DWGRNet 二、实验总结 文章链接 https://arxiv.org/pdf/2405.04101 摘要 本博客介绍了论文《Continual lea…...

【MySQL】数据操作
数据操作 一、INSERT1、介绍2、语法3、语法介绍4、注意事项5、示例 二、插入否则更新1、介绍2、语法3、语法介绍4、示例 三、ROW_COUNT1、介绍2、示例 四、REPLACE1、介绍2、语法3、示例 五、UPDATE1、介绍2、语法3、示例 六、DELETE1、介绍2、语法3、语法介绍 七、TRUNCATE1、…...

python数据分析:使用pandas库读取和编辑Excel表
使用 Pandas,我们可以轻松地读取和写入Excel 文件,之前文章我们介绍了其他多种方法。 使用前确保已经安装pandas和 openpyxl库(默认使用该库处理Excel文件)。没有安装的可以使用pip命令安装: pip install pandas ope…...

开源轻量级文件分享服务Go File本地Docker部署与远程访问
???欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学习,不断总结,共同进步,活到老学到老…...
异步背后的奥秘:事件循环
异步背后的奥秘:事件循环 复习环节 JavaScript运行时 我们都知道,JavaScript本身是一个单线程的,那JavaScript是如何处理同时发生的多个任务的呢? 首先JavaScript引擎运行在一个容器中,这个容器可能是浏览器或者nod…...

Springboot使用RabbitMQ实现关闭超时订单的一个简单示例
1.maven中引入rabbitmq的依赖: <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-amqp</artifactId></dependency> 2.application.yml中进行rabbitmq相关配置: # rabbit…...

小程序基础 —— 07 创建小程序项目
创建小程序项目 打开微信开发者工具,左侧选择小程序,点击 号即可新建项目: 在弹出的新页面,填写项目信息(后端服务选择不使用云服务,开发模式为小程序,模板选择为不使用模板)&…...
【Golang 面试题】每日 3 题(十五)
✍个人博客:Pandaconda-CSDN博客 📣专栏地址:http://t.csdnimg.cn/UWz06 📚专栏简介:在这个专栏中,我将会分享 Golang 面试中常见的面试题给大家~ ❤️如果有收获的话,欢迎点赞👍收藏…...

Docker命令(用法说明详解)
一、常见Docker容器命令 #根据image创建一个新容器并运行(即使该image已经存在容器,也会再创建一个新容器) docker run IMAGE_NAME #根据image创建一个新容器并运行。 #选项-d:指定容器为后台运行,--name自定义该容器…...
leetcode 热题100(131. 分割回文串)c++
链接:131. 分割回文串 - 力扣(LeetCode) 给你一个字符串 s,请你将 s 分割成一些子串,使每个子串都是 回文串 。返回 s 所有可能的分割方案。 示例 1: 输入:s "aab" 输出ÿ…...

vs2022编译opencv 4.10.0
参考:Windosw下Visual Studio2022编译OpenCV与参考区别在于,没有用cmake GUI,也没有创建build目录,直接用vs2022打开了C:\code\opencv目录,即CMakeLists.txt所在根目录。没有修改默认下载地址,采用手动下载…...

大数据零基础学习day1之环境准备和大数据初步理解
学习大数据会使用到多台Linux服务器。 一、环境准备 1、VMware 基于VMware构建Linux虚拟机 是大数据从业者或者IT从业者的必备技能之一也是成本低廉的方案 所以VMware虚拟机方案是必须要学习的。 (1)设置网关 打开VMware虚拟机,点击编辑…...

【机器视觉】单目测距——运动结构恢复
ps:图是随便找的,为了凑个封面 前言 在前面对光流法进行进一步改进,希望将2D光流推广至3D场景流时,发现2D转3D过程中存在尺度歧义问题,需要补全摄像头拍摄图像中缺失的深度信息,否则解空间不收敛…...
渲染学进阶内容——模型
最近在写模组的时候发现渲染器里面离不开模型的定义,在渲染的第二篇文章中简单的讲解了一下关于模型部分的内容,其实不管是方块还是方块实体,都离不开模型的内容 🧱 一、CubeListBuilder 功能解析 CubeListBuilder 是 Minecraft Java 版模型系统的核心构建器,用于动态创…...
生成 Git SSH 证书
🔑 1. 生成 SSH 密钥对 在终端(Windows 使用 Git Bash,Mac/Linux 使用 Terminal)执行命令: ssh-keygen -t rsa -b 4096 -C "your_emailexample.com" 参数说明: -t rsa&#x…...

【JavaWeb】Docker项目部署
引言 之前学习了Linux操作系统的常见命令,在Linux上安装软件,以及如何在Linux上部署一个单体项目,大多数同学都会有相同的感受,那就是麻烦。 核心体现在三点: 命令太多了,记不住 软件安装包名字复杂&…...

dify打造数据可视化图表
一、概述 在日常工作和学习中,我们经常需要和数据打交道。无论是分析报告、项目展示,还是简单的数据洞察,一个清晰直观的图表,往往能胜过千言万语。 一款能让数据可视化变得超级简单的 MCP Server,由蚂蚁集团 AntV 团队…...
在web-view 加载的本地及远程HTML中调用uniapp的API及网页和vue页面是如何通讯的?
uni-app 中 Web-view 与 Vue 页面的通讯机制详解 一、Web-view 简介 Web-view 是 uni-app 提供的一个重要组件,用于在原生应用中加载 HTML 页面: 支持加载本地 HTML 文件支持加载远程 HTML 页面实现 Web 与原生的双向通讯可用于嵌入第三方网页或 H5 应…...

JVM 内存结构 详解
内存结构 运行时数据区: Java虚拟机在运行Java程序过程中管理的内存区域。 程序计数器: 线程私有,程序控制流的指示器,分支、循环、跳转、异常处理、线程恢复等基础功能都依赖这个计数器完成。 每个线程都有一个程序计数…...
JavaScript 数据类型详解
JavaScript 数据类型详解 JavaScript 数据类型分为 原始类型(Primitive) 和 对象类型(Object) 两大类,共 8 种(ES11): 一、原始类型(7种) 1. undefined 定…...

网页端 js 读取发票里的二维码信息(图片和PDF格式)
起因 为了实现在报销流程中,发票不能重用的限制,发票上传后,希望能读出发票号,并记录发票号已用,下次不再可用于报销。 基于上面的需求,研究了OCR 的方式和读PDF的方式,实际是可行的ÿ…...