目录
1 通讯协议
2 TCP/IP 网络模型
2.1 TCP协议
2.1.1 TCP 连接过程
2.1.2 TCP 断开连接
2.1.3 TCP协议特点
2.2 UDP协议
2.2.1 UDP 协议特点
3 应用层协议简介
3.1 HTTP 协议
3.2 CoAP 协议
3.3 MQTT 协议
4 CoAP 协议详解
4.1 REST 风格
4.2 CoAP 首部分析
4.3 CoAP 媒体类型
4.4 CoAP 重传机制
4.5 CoAP 报文解析
1 通讯协议
通讯协议又称通讯规程,是通信双方对数据传送控制的一种约定,双方必须共同准守。约定的内容包括:数据格式、同步方式、传送速度、传送速度、传送步骤、检纠错方式、控制字符定义等。双方实体需要准守通信协议中既定的规则,才能将有意义的信息传递给对方。
市面上有很多物联网应用层协议,COAP、HTTP、MQTT 是最常见的三种。HTTP 和 MQTT 均使用 TCP 作为传输层协议,而 COAP 则是基于 UDP 传输协议。同时,传输层的 UDP 和 TCP 协议又都是依赖网络层的 IP 技术。
2 TCP/IP 网络模型
TCP/IP 是互联网相关的各类协议族的总称,比如 TCP、UDP、IP、FTP、HTTP、SMTP 等都属于 TCP/IP 族内的协议。
TCP/IP 模型是互联网的基础,它是一系列网络协议的总称。这些协议可以划分为四层,分别为链路层、网络层、传输层和应用层。
链路层:负责封装和解封装 IP 报文,发送和接收 ARP 和 RARP 报文等。
网络层:负责路由以及把分组报文发送给目标网络或主机。
传输层:负责对报文进行分组和重组,并以 TCP 或 UDP 协议格式封装报文。
应用层:负责向用户提供应用程序,比如 HTTP、COAP、Telnet、MQTT、DNS 等。
在网络体系结构中,网络通讯的建立必须是在通讯双方在对等层进行,不能交错。在整个数据传输过程中,数据在发送端时经过各层都要附加上相应层的协议头和协议尾(仅数据链路层需要封装协议尾)部分,也就是要对数据进行协议封装,以标识对应层所用的通讯协议。
2.1 TCP协议
当一台计算机想要与另一台计算机通讯时,两台计算机之间的通行需要畅通且可靠,这样才能保证正确收发数据。例如,当你想查看网页或查看电子邮件时,希望完整且按顺序查看网页,而不丢失任何内容。当你下载文件时,希望获得的是完整的文件,而不仅仅是文件的一部分,于是就用到了 TCP 。
TCP(Transmission Control Protocol,传输控制协议),是是一种面向连接的、可靠的、基于字节流得到传输层通信协议,由 IETF 的 RFC 793 定义。TCP 是面向连接的、可靠的流协议,流是指不间断的数据结构,你可以把它想象成排水管中的水流。
2.1.1 TCP 连接过程
如下图所示,可以看到建立一个 TCP 连接的过程(三次握手的过程):
第一次握手:客户端发送 SYN(SEQ=x)报文给服务器,进入 SYN_SEND 状态
第二次握手:服务端接收到 SYN 报文,回应一个 SYN(SEQ=y)+ ACK(ACK=x+1)报文,并进入 SYN_RECV 状态。
第三次握手:客户端收到服务端的 SYN 报文,回应一个 ACK(ACK=y+1)报文,进入连接(Established)状态。
为了防止出现失效的连接请求报文被服务端接收的情况,从而产生错误,这个就是为什么 TCP 建立连接需要三次握手,而不是两次的原因。
通过 wireshark 抓包工具我们也能复现这个过程:
2.1.2 TCP 断开连接
建立一个连接需要三次握手,而终止一个连接需要进经过四次握手,这是由于 TCP 的半关闭造成的,具体过程如下图所示:
第一次握手:某个应用进程首先调用 close,称该端执行 “主动关闭(active close)”,该端的 TCP 于是发送一个 FIN 字节,表示数据发送完毕。
第二次握手:接收到这个 FIN 的队端执行 “被动关闭(passive close)”,这个 FIN 由 TCP 确认。
注意:FIN 的接收也作为一个文件结束符(end-of-file)传递给接收端应用进程,放在已排队等候该应用进程接收的任何其他数据之后,因为,FIN 的接收意味着接收端应用进程在相应连接上再无额外数据可接收。
第三次握手:一段时间后,接收到这个文件结束符的应用进程将调用 close 关闭它的套接字。这导致它的 TCP 也发送一个 FIN。
第四次握手:接收这个最终 FIN 的原发送端 TCP(即执行主动关闭的那一端)确认这个 FIN。
既然每个方向都需要一个 FIN 和一个 ACK,因此通常需要4个分节。
如下,通过 wireshark 抓包工具我们也能复现断开连接的过程:
2.1.3 TCP协议特点
面向连接
面向连接,是指发送数据之前必须在两端建立连接。建立连接的方法是 ”三次握手“,这样能建立可靠的连接。
仅支持单传播
每条 TCP 传输连接只能有两个端点,只能进行点对点的数据传输,不支持多端和广播传输方式。
面向字节流
TCP 不像 UDP 那样一个个报文独立的传输,而是在不保留报文边界的情况下已字节流方式进行传输。
可靠传输
对于可靠传输,判断丢包、误码靠的是 TCP 的段编号以及确认号。
提供拥塞控制
当网络出现拥塞的时候,TCP 能够减小向网络注入数据的速率和数量,缓解拥塞。
TCP 提供全双工通信
TCP 允许通信双方的应用程序在任何时候都能发送数据,因为 TCP 连接的两端都没有缓存,用来临时存放存放双向通信的数据。当然,TCP可以立即发送一个数据段,也可以缓存一段时间以便一次发送更多的数据段。
TCP 协议报文格式:
源端口号(2字节):源设备上发送数据包进程的16位端口号。
目标端口号(2字节):目标设备上接收进程的16位端口号。
序号(4字节):由滑动窗口确认系统使用,作为数据分包的第一个字节的序号。在 SYN 位置为1的情况下,它表示初始序号。
确认号(4字节):如果 ACK 位置为1,该字段有效并包含设备用于对接收到的数据包进行确认的序号。
数据偏移(4位):表示数据包的开始位置与 TCP 首部的开始处偏移多少个 32位(4字节)的偏移量。该字段的值乘以4才得到字节形式表示的偏移量、
控制位(6位):用于相关控制信息。这些控制信息包括 URG 紧急位、ACK 确认位、PUSH 推送位、RST 复位位、SYN 同步位和 FIN 结束位。
窗口(2字节):用于流控制,表示该数据包的发送者在一定时间内能从其他设备接收的字节数。
校验和(2字节):用于检测错误的 16 位校验和。
紧急指针(2字节):如果 URG 位置为1,该字段包含紧急数据后面的 “正常” 数据的第一字节的序列号。
2.2 UDP协议
UDP(User Datagram Protocol,用户数据报协议),在网络中它与 TCP 协议一样用于处理数据包,是一种无连接的协议。在 OSI 模型中,在第四层传输层,处于 IP 协议的上一层。UDP 有不提供数据包分组、组装和不能对数据包进行排序的特点,也就是说,当报文发送之后,是无法得知其是否安全完整到达的。
2.2.1 UDP 协议特点
面向无连接
首先 UDP 是不需要和 TCP 一样在发送数据前进行三次握手建立连接的,想发数据就可以开始发送了,并且也只是数据报文的搬运工,不会对数据报文进行任何拆分和拼接操作。
具体来说就是:
在发送端,应用层将数据传递给传输层的 UDP 协议,UDP 只会给数据增加一个 UDP 头,标识下是 UDP 协议,然后就传递给网络层了。
在接收端,网络层将数据传递给传输层,UDP 只去除 IP 报文头后就传递给应用层,不会进行任何拼接操作。
有单播,多播和广播的功能
UDP 不只支持一对一的传输方式,同样支持一对多,多对多,多对一的方式,也就是说 UDP 提供了单播、多播、广播的功能。
UDP 是面向报文的
发送方的 UDP 对应用程序交下来的报文,在添加首部后就向下交付 IP 层。UDP 对应用层交下来的报文,既不合并,也不拆分,而是保留这些报文的边界。因此应用程序必须选择合适大小的报文。
不可靠性
首先不可靠性体现在无连接上,通信都不需要建立连接,想发送就发送,这样的情况肯定不可靠。并且收到什么数据就传递什么数据,并且也不会备份数据,发送数据也不会关心对方是否已经正确接收到数据了。
再者网络环境时好时坏,但是 UDP 因为没有拥塞控制,一直会以恒定的速度发送数据。即使网络条件不好,也不会对发送速率进行调整,这样实现的弊端就是在网络条件不好的情况下可能会导致丢包,但是优点也很明显,在某些实时性要求高的场景(比如电话会议、直播等)就需要使用 UDP 而不是 TCP。
头部开销小,传输数据报文时是很高效的
UDP 头部包含了以下几个数据:
两个十六位的端口号,分别为源端口(可选字段)和目标端口。
整个数据报文的长度。
整个数据报文的校验和(IPv4 可选字段),该字段用于发现头部信息和数据中的错误。
因此 UDP 的头部开销小,只有八字节,相比 TCP 的至少二十字节要少的多,在传输数据报文时是很高效的。
3 应用层协议简介
3.1 HTTP 协议
HTTP 协议,即超文本传输协议(Hypertext Transfer Protocol),是一种详细规定了浏览器和万维网服务器之间互相通信的规则,通过因特网传送万维网文档得到数据传送协议。
目前 HTTP 协议作为 WEB 的标准协议已被广泛使用,它在一些物联网场景中同样可以使用,例如手机、PC等终端设备。但是作为适应浏览器场景的 HTTP 协议,并不适用于物联网的其他设备。
适用范围:开放物联网中的资源,实现服务被其他应用所调用。
优势:
简单的工作模式,请求 / 响应。
完整的方法定义。
合理的状态码设计。
友好的媒体类型支持,如文本、图片、视频等。
缺点:
单向传输,可以通过客户端轮询实现类似推送效果或者HTTP2.0
安全性不高,HTTP是明文协议,可以使用 HTTPS 传输。
HTTP 是文本协议,冗长的协议头部,对于运算、存储、带宽资源受限的设备来说开销大。
3.2 CoAP 协议
CoAP(Constrained Application Protocol)即受限的应用协议。CoAP 是为了让低功耗受限设备可以接入互联网,由 IETF 组织制定的,它借鉴了 HTTP 大量成功经验,同样使用请求 / 响应工作模式。
使用范围:适用于互联网环境下一对一 M2M 通讯。
优势:
采用和 HTTP 相似语义的请求和响应码,使用二进制报文,报文大小较小。
传输层基于 UDP 协议,比 TCP 数据包小,并不需要建立连接带来握手的开销。
资源发送支持,通过观察者模式实现类似发布 / 订阅效果。
缺点:
基于 UDP 的不可靠传输,但通过四种报文类型的组合及重传机制提高了传输的可靠性。
基于 UDP 的无连接传输,不利于不同网络间消息的回传。
3.3 MQTT 协议
MQTT(Message Queuing Telemetry Transport)即消息队列遥测传输。
MQTT 协议最初是在 1999 年由 IBM 公司开发的,用于将石油管道上的传感器与卫星相连接。2014 年正式成为 OASIS 开放标准。
MQTT 使用类似 MQ 常用的发布 / 订阅模式,起到应用程序解耦、异步消息、削峰填谷的作用。很多 MQ 中间件也支持 MQTT 协议,比如 ActiveMQ、RabbitMQ、Kafka 等。
适用范围:在低带宽、不可靠的网络下提供基于云平台的远程设备的数据传输和监控。
优势:
使用发布 / 订阅模式,提供一对多的消息发布,使消息发送者和接受者在时间和时空上解耦。
二进制协议,网络传输开销非常小(固定头部是2字节)。
灵活的 Topic 订阅、QoS 等特性。
缺点:
集中化部署,服务端压力大,需要考虑流程控制及高可用。
对于请求 / 响应模式的支持需要在应用层根据消息 ID 做发布主题和订阅主题之间的关联。
4 CoAP 协议详解
4.1 REST 风格
REST(具象状态传输)是 Roy Thomas Fielding 博士于2000年在他的博士论文 “Architectural Styles and the Design of Network-based SoftwareArchitectures” 中提出来的一种 Web 软件架构风格。目前在三种主流的 Web 服务实现方案中,REST 模式与复杂的 SOAP 和 XML-RPC 相比更加简洁,越来越多的 Web服务 开始采用 REST 风格设计和实现。REST 是设计风格而不是标准,REST 通常基于使用 HTTP、URI、XML、JSON 和HTML 这些现有的协议和标准来实现。
REST 风格具有以下特点:
资源一般由 URI 来指定。
无状态通信。
对资源的操作包括获取、创建、修改和删除等,这些操作对应 HTTP 的 GET、POST、PUT 和 DELETE 方法。
资源的表现形式可以是 XML、JSON 或 HTML 格式文件。
CoAP 基于 REST 架构风格,基于简洁、清晰,且易于实现的特点。CoAP 和 HTTP 一样,使用请求 / 响应工作模式:客户端发送 CoAP请求,服务器一旦侦听到请求便会根据其包含的 URI 对资源进行定位,并按请求方法决定如何操作该资源:读取(GET)、创建(POST)、修改(PUT)或者删除(DELETE)。服务器处理完请求之后,将返回客户端一个 CoAP响应,其中包含响应码,也有可能有响应内容。
虽然 CoAP 和 HTTP 多有相似,但其较 HTTP 简单的多。CoAP 建立在 UDP 栈上,这是与 HTTP 相比最主要的区别,它可以更快更好的进行资源优化。CoAP 可以使用与 10kb RAM 系统上,占用内存较少,同时,CoAP 能够发现网络中的节点,这对于低功耗无线传感器网络的自治金额自我修复设计非常有用。
4.2 CoAP 首部分析
CoAP 是一个完整的二进制应用层协议,和 TCP/IP 协议族中的其他协议一样,CoAP协议带有报文头,负载(Payload)和报文头之间使用单字节分隔符 0xFF 隔离。报文头里的版本编号 Ver、报文类型 T、标签长度指示 TKL、准则 Code、报文序号 MessageID 为必填内容。
CoAP 协议报文结构如下:
【 Ver 】版本编号,占2位,取固定值 0b01(0b开头表示后面的数据为二进制数);
【 T 】报文类型,占2位,CoAP 协议定义了4种不同形式的报文:CON、NON、ACK、RST :
【 TKL 】标签长度指示,占4位,用于指示 Token 区域的具体长度。当 CoAP 报文包含 Token 时,TKL 取值 0b0001(1个字节长度)、0b0010(2个字节长度)、0b0100(4个字节长度),当 CoAP 报文省略 Token 时,TKL 取值 0b0000。
【 Code 】准则,占8位(一个字节)。Code 的值分为高三位 Class 部分和低五位 Detail 部分,采用 c.dd 的形式描述:c 和 dd 均采用十进制,c 的取值范围是 031。Code 在请求和响应中的具体表现显示有所不同:当 c=0 时,表示 CoAP 请求,否则表示 CoAP 响应。Code=0.00 表示空报文,是一种特殊形式的 CoAP 响应,Code 值与表达含义如下:
【 Message ID 】报文序号,占2个字节,并采用大端格式描述,用于客户端和服务器建立请求和响应报文之间的一一对应关系,即起报文确认作用。一组对应的 CoAP 请求和 CoAP 响应使用相同的 Message ID,在同一次会话中 ID 保持不变,此次会话结束后该 ID 将会被回收利用。Message ID 可以弥补 UDP 传输方式带来的不可靠性。
【 Token 】标签,长度由 TKL 定义,可以是1字节、2字节或4字节。通常用于应用确认。
【 Options 】选项,CoAP 请求或响应中可携带一组或多组 Options,功能类似于 HTTP 中的通信首部字段、请求首部字段、响应首部字段和实体首部字段。Options 是 CoAP 核心协议中较为复杂的部分,但 Option 也给 CoAP 的应用带来了诸多灵活性。CoAP 选项包括 Uri-Host、Uri-Port、Uri-Path、Uri-Query、Content-Format、Accept、Etag、If-Match和If-None-Match 等部分。
Option Delta: 占4位,转换为10进制数值范围在0~12之间 。
如果 Option Delta == 13,那么 Option Delta (extended) 部分为 1 字节,Option Delta = 13 + Option Delta(extended)
如果 Option Delta == 14,那么 Option Delta (extended) 部分为 2 字节,Option Delta = 14 + 255 + Option Delta(extended)
Option Delta == 15 无效
Option Length: 占4位, 转换为10进制数值范围在0~12之间 。
如果 Option Length == 13,那么 Option Length (extended) 部分为 1 字节,Option Length = 13 + Option Length(extended)
如果 Option Length == 14,那么 Option Length (extended) 部分为 2 字节,Option Length = 14 + 255 + Option Length(extended)
Option Delta == 15 无效
Option Value: 由 Option Length 的值决定 Option Value 的长度。
Option Delta 对应值的含义如下:
3 Uri-Host:CoAP 主机名称,例如 iot.eclipse.org
7 Uri-Port:CoAP 端口号,默认为5683
11 Uri-Path:资源路由或路径,例如 \temperature。资源路径采用 UTF8 字符串形式,不计 \ 的长度。
15 Uri-Query:访问资源参数,例如 ?value1=1&value2=2,参数与参数之间使用 “&” 分隔,Uri-Query 和 Uri-Path之间采用“?”分隔。
在这些option中,Content-Format 和 Accept 用于表示CoAP负载的媒体格式。
12 Content-Format:指定 CoAP 复杂媒体类型,媒体类型采用整数描述,例如 application/json 对应整数50,application/octet-stream 对应整数40。
17 Accept:指定 CoAP 响应复杂中的媒体类型,媒体类型的定义和 Content-Format 相同。
【 0xFF 】分隔符,占1个字节,用于区分 CoAP 首部和具体负载。
【 Payload 】负载,正在有用的被交互的数据。CoAP 负载可能包含不同的媒体类型:二进制、文本、XML、JSON、CBOR 等,但并不支持 HTML 类型的负载。
4.3 CoAP 媒体类型
CoAP 负载支持多种媒体类型,并采用编号的方式对其进行定义。编号一般为2字节的无符号整数。
文本类型(text/plain)、二进制类型(application/octet-stream)、JSON类型(application/json)是在物联网中应用最广泛的三种媒体类型,application/link-format 则是专属于 CoAP 的媒体类型,一般在 CoAP 资源发现中使用。
(一)文本类型
CoAP 中默认的媒体类型为文本类型,若负载为文本类型,那么 CoAP 请求和响应都不需要指定 Content-Format。虽然文本类型使用方便,但需要提前对负载结果的每个部分按顺序进行定义。
如传感器的数据:21.3,62,2022-01-01 17:31:10,传输双方需要事先约定第一个值表示 ”温度“,第二个值表示 ”湿度“,第三个值表示 ”时间“,数据才能被正确解析。
(二)二进制类型
TLV 形式的二进制负载也经常出现在某些物联网应用中出现。TLV 是 Tag,Length 和 Value 的缩写,一个基本的数据元就包含上面三个域。Tag 是该数据元的唯一标识,Length 是 Value 域的长度,Value 就是数据本身。Type 和 Length 的长度固定,一般为 2 或 4 个字节,Value 的长度由 Length 指定,如字符串 9F0607A0000000031010,其中 9F06 是 Tag,07 是长度,A0000000031010 就是数据本身。
(三)JSON类型
JSON(JavaScript Object Notation,JS对象表示法)是一种轻量级的数据交换格式,易于使用者阅读和编写,也易于机器解析和生成。JSON 分为 JSON对象和 JSON 数组两种构造结构:
JSON 对象
JSON 对象是一个无序的键值对集合,以 { 开始并以 } 结束,每个键后面跟一个分号 :,每组键值对之间使用逗号 , 分隔。
JSON 数组
JSON 数组是值有有序集合,以 [ 开始并以 ] 结束,值之间使用逗号 , 分隔。
4.4 CoAP 重传机制
由于 CoAP 采用 UDP 作为其传输层协议,故在网络数据传输过程中,无论是请求还是响应,均存在丢包的风险。为此,CoAP 设计了双层结构 -- 消息层和请求/响应层,消息层处理端点之间的数据交换,并为各报文类型提供重传机制,来弥补传输过程中的不可靠性。
前面提到过,CoAP 定义了四种不同类型的报文:CON、NON、ACK、RST。CON 报文需要被接受者确认,即每一个 CON 报文都对应一个准确热 ACK 报文或 RST 报文,如果在规定的时间内客户端未接受到 ACK 报文或 RST 报文,那么客户端将启动 “重传机制”,如:
在某个时刻,CoAP 客户端发起 CON 类型的 GET 请求,试图从服务端获得温度传感器数据 temperature。如请求没有准确到达 CoAP 服务器(称作 “CoAP 请求丢失”),或服务器虽收到请求并返回响应,但响应未正确到达客户端(称作 “CoAP 响应丢失”),超过一定时间后,客户端就会将前一次 CoAP 请求判定为失败,并再次发送同样的 GET 请求,两次请求的首部和负载完全相同。
CoAP 报文重传机制受制于 ACK_TIMEOUT、ACK_RAMDOM_FACTOR、MAX_RETRANSMIT 三个参数。ACK_TIMEOUT 是响应等待超时时间,典型值为 2s,ACK_RAMDOM_FACTOR 是一个不小于1的随机系数,典型值取1.5,MAX_RETRANSMIT 表示最大重传次数,典型值为4:
对于一个 CON 报文而言,初始超时时间是 ACK_TIMEOUT 到 ACK_RAMDOM_FACTOR * MAX_RETRANSMIT 之间的随机数。重传计数器从0开始计数,一旦在初始超时时间内客户端未收到服务器回传的 ACK 报文或 RST 报文,那么 CON 报文将会被重新发送,重传计数器自动增加至1,并且下一次重传超时间自动递增为上一次超时时间的两倍。
假设响应等待超时时间 ACK_TIMEOUT 取2s,随机系数 ACK_RAMDOM_FACTOR 取1.5,最大重传次数 MAX_RETRANSMIT 为4,则初始超时时间是2~3s之间的随机数(本例中我们取2.5s)。最极端的情况下,CoAP 客户端会发送一次正常的 CON 报文,并在重传4次后停止对该报文的传输。
在该过程中,相邻 CON 报文的时间间隔分别为 2.5s、2 * 2.5s、4 * 2.5s、8 * 2.5s,总计时间即最大传输时间 MAX_TRANSMIT_SPAN = 2.5 * (1 + 2 + 8) = 37.5s。
最后一次 CON 报文的重传并不意味整个传输过程已经结束,CoAP 客户端还要等待最后一次超时时间:16 * 2.5s,然后将停止本条报文的传输。从 CoAP 客户端发送第一次 CON 报文到最后停止传输,总共消耗的时间称为最大等待时间 MAX_TRANSMIT_WAIT = 2.5 *(1+2+4+8+16)= 77.5s。
4.5 CoAP 报文解析
以 电信 OC 平台上设备登录报文为例:
4402AD3D3DAD0700B272641128396C776D326D3D312E300D0565703D38363131303730353937333934353903623D55066C743D333030FF3C2F3E3B72743D226F6D612E6C776D326D222C3C2F312F303E2C3C2F322F303E2C3C2F332F303E2C3C2F342F303E2C3C2F352F303E2C3C2F362F303E2C3C2F372F303E2C3C2F31392F303E2C3C2F31392F313E
上述报文为十六进制数据,根据 [CoAP 首部分析](### CoAP 首部分析) 可以将报文分成7个部分:
① 44: 1字节,转换为二进制可得 0b01000100,对应Ver、T、TKL 的值为:
② 02: 1字节,Code 准则,转换为二进制可得 0b00000010,对应 Code 值为:
③ AD3D: 2字节,Message ID 报文序号,对应的值为:
④ 3DAD0700: 4字节,表示Token值, TLK 可知此报文 Token 长度为4字节,故此处截取4字节长度 Token 值。
⑤ B272641128396C776D326D3D312E300D0565703D38363131303730353937333934353903623D55066C743D333030: Options选项,
由 Option Delta 和 Option Length 占一个字节,故取 B2 先进行解析,转换为二进制数为 0b10110010,Option Delta 和 Option Length 解析为:
Option Value 取2个字节长度为:7264,转ASSIC为 rd,此 Option 表示为 uri-path=/rd。
继续往下,截取 11,转换为二进制数为 0b00010001,Option Delta 和 Option Length 解析为 1、1,累加上第一个偏移量为 11 + 1 = 12,对应的 Option 选项名称为 Content-Format ,Option Value 长度为1,故值截取为 28,转换为十进制数为 40 ,对应 CoAP 媒体类型为 application/link-format。
截取 39,转为为二进制数为 0b00111001,Option Delta 和 Option Length 解析为 3、9,累加前面的偏移量为 12 + 3 = 15,对应的 Option 选项名称为 Uri-Query,Option Value 长度为9,故值截取为 6C776D326D3D312E30,进行 ASCII 转换可以得到值为 lwm2m=1.0。
截取 0D,转为二进制数为 0b00001101,Option Delta 和 Option Length 解析为 0、13,由于 Option Length 为 13,故下面还含有 Option Delta(extended) 和 Option Length(extended),截取 05 可得二进制数 0b00000101,Option Delta(extended) 和 Option Length(extended) 解析为 0、5,故 Option Length 值为 13 + 5 = 18,即 Option Value 的长度为18,截取 65703D383631313037303539373339343539,可得值为 ep=861107059739459。
截取 03,转为二进制数得 0b00000011,Option Delta 和 Option Length 解析为 0、3,累加前面的偏移量为 15 + 0 = 15,对应的 Option 选项名称为 Uri-Query,Option Value 长度为3,故值截取为 623D55,进行 ASCII 转换可以得到值为 b=U。
截取 06,转为二进制数得 0b00000110,Option Delta 和 Option Length 解析为 0、6,累加前面的偏移量为 15 + 0 = 15,对应的 Option 选项名称为 Uri-Query,Option Value 长度为6,故值截取为 6C743D333030,进行 ASCII 转换可以得到值为 lt=300。
Uri-Query 参数与参数之间使用 & 符号隔开,故此参数完整形式为 lwm2m=1.0&ep=861107059739459&b=U<=300。
⑥ FF: 1个字节,分隔符,用于区分 CoAP 首部 与 负载数据。
⑦ 3C2F3E3B72743D226F6D612E6C776D326D222C3C2F312F303E2C3C2F322F303E2C3C2F332F303E2C3C2F342F303E2C3C2F352F303E2C3C2F362F303E2C3C2F372F303E2C3C2F31392F303E2C3C2F31392F313E: Payload 负载数据,ASSIC 转换后得 </>;rt="oma.lwm2m",</1/0>,</2/0>,</3/0>,</4/0>,</5/0>,</6/0>,</7/0>,</19/0>,</19/1> ,与 OC 平台文档 要求一致。