Skip to main content

3. Message Format (消息格式)

CoAP基于紧凑消息的交换, 默认情况下通过UDP传输 (即, 每条CoAP消息占用一个UDP数据报的数据部分). CoAP也可以通过数据报传输层安全 (DTLS, Datagram Transport Layer Security) 使用 (见第9.1节). 它也可以通过其他传输方式使用, 例如SMS, TCP或SCTP, 其规范超出了本文档的范围. (CoAP不支持UDP-lite [RFC3828] 和UDP零校验和 [RFC6936].)

CoAP消息以简单的二进制格式编码. 消息格式以固定大小的4字节头部开始. 后面是可变长度的Token值, 其长度可以在0到8字节之间.

在Token值之后是零个或多个TLV (Type-Length-Value) 格式的CoAP选项序列, 可选地后跟占用数据报其余部分的有效载荷.

 0                   1                   2                   3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|Ver| T | TKL | Code | Message ID |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Token (if any, TKL bytes) ...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Options (if any) ...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|1 1 1 1 1 1 1 1| Payload (if any) ...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

图 7: 消息格式

头部中的字段定义如下:

Version (Ver, 版本): 2位无符号整数. 表示CoAP版本号. 本规范的实现必须将此字段设置为1 (二进制01). 其他值保留供将来版本使用. 具有未知版本号的消息必须被静默忽略.

Type (T, 类型): 2位无符号整数. 表示此消息是可确认 (0), 不可确认 (1), 确认 (2), 还是重置 (3) 类型. 这些消息类型的语义在第4节中定义.

Token Length (TKL, Token长度): 4位无符号整数. 表示可变长度Token字段的长度 (0-8字节). 长度9-15是保留的, 不得发送, 并且必须作为消息格式错误处理.

Code (代码): 8位无符号整数, 分为3位类别 (最高有效位) 和5位详细信息 (最低有效位), 记录为"c.dd", 其中"c"是3位子字段的0到7的数字, "dd"是5位子字段的00到31的两位数字. 类别可以表示请求 (0), 成功响应 (2), 客户端错误响应 (4), 或服务器错误响应 (5). (所有其他类别值都是保留的.) 作为特殊情况, 代码0.00表示空消息. 对于请求, 代码字段表示请求方法; 对于响应, 表示响应码. 可能的值在CoAP代码注册表 (第12.1节) 中维护. 请求和响应的语义在第5节中定义.

Message ID (消息ID): 16位无符号整数, 以网络字节顺序. 用于检测消息重复并将确认/重置类型的消息与可确认/不可确认类型的消息匹配. 生成消息ID和匹配消息的规则在第4节中定义.

头部后面是Token值, 其长度可以是0到8字节, 由Token长度字段给出. Token值用于关联请求和响应. 生成Token和关联请求和响应的规则在第5.3.1节中定义.

头部和Token后面是零个或多个选项 (第3.1节). 选项可以后跟消息结束, 另一个选项, 或有效载荷标记和有效载荷.

在头部, token和选项 (如果有) 之后是可选的有效载荷. 如果存在且长度非零, 它以固定的单字节有效载荷标记 (0xFF) 为前缀, 该标记表示选项的结束和有效载荷的开始. 有效载荷数据从标记之后延伸到UDP数据报的末尾, 即, 有效载荷长度是从数据报大小计算的. 缺少有效载荷标记表示零长度有效载荷. 标记后跟零长度有效载荷的存在必须作为消息格式错误处理.

实现注意: 字节值0xFF也可能出现在选项长度或值中, 因此简单地逐字节扫描0xFF不是查找有效载荷标记的可行技术. 字节0xFF仅在可能出现另一个选项开始的地方才具有有效载荷标记的含义.

3.1. Option Format (选项格式)

CoAP定义了可以包含在消息中的多个选项. 消息中的每个选项实例指定定义的CoAP选项的选项编号, 选项值的长度和选项值本身.

实例必须按照其选项编号的顺序出现, 而不是直接指定选项编号, 并且在它们之间使用增量编码: 每个实例的选项编号计算为其增量与消息中前一个实例的选项编号之和. 对于消息中的第一个实例, 假设前面有一个选项编号为零的选项实例. 通过使用增量为零, 可以包含同一选项的多个实例.

选项编号在"CoAP选项编号"注册表 (第12.2节) 中维护. 有关本文档中定义的选项的语义, 请参见第5.4节.

  0   1   2   3   4   5   6   7
+---------------+---------------+
| | |
| Option Delta | Option Length | 1 byte
| | |
+---------------+---------------+
\ \
/ Option Delta / 0-2 bytes
\ (extended) \
+-------------------------------+
\ \
/ Option Length / 0-2 bytes
\ (extended) \
+-------------------------------+
\ \
/ /
\ \
/ Option Value / 0 or more bytes
\ \
/ /
\ \
+-------------------------------+

图 8: 选项格式

选项中的字段定义如下:

Option Delta (选项增量): 4位无符号整数. 0到12之间的值表示选项增量. 三个值保留用于特殊结构:

  • 13: 初始字节后跟一个8位无符号整数, 表示选项增量减13.

  • 14: 初始字节后跟一个网络字节顺序的16位无符号整数, 表示选项增量减269.

  • 15: 保留用于有效载荷标记. 如果字段设置为此值但整个字节不是有效载荷标记, 则必须作为消息格式错误处理.

结果选项增量用作此选项的选项编号与前一个选项 (对于第一个选项为零) 的选项编号之间的差异. 换句话说, 选项编号是通过简单地将此选项和之前所有选项的选项增量值相加来计算的.

Option Length (选项长度): 4位无符号整数. 0到12之间的值表示选项值的长度 (以字节为单位). 三个值保留用于特殊结构:

  • 13: 选项值之前有一个8位无符号整数, 表示选项长度减13.

  • 14: 选项值之前有一个网络字节顺序的16位无符号整数, 表示选项长度减269.

  • 15: 保留供将来使用. 如果字段设置为此值, 则必须作为消息格式错误处理.

Value (值): 恰好为选项长度字节的序列. 选项值的长度和格式取决于相应的选项, 该选项可以定义可变长度值. 有关本文档中使用的格式, 请参见第3.2节; 其他文档中定义的选项可以使用其他选项值格式.

3.2. Option Value Formats (选项值格式)

本文档中定义的选项使用以下选项值格式.

empty (空): 零长度字节序列.

opaque (不透明): 不透明的字节序列.

uint (无符号整数): 非负整数, 使用选项长度字段给出的字节数以网络字节顺序表示.

选项定义可以指定允许的字节数范围; 如果有选择, 发送者应该用尽可能少的字节表示整数, 即, 没有前导零字节. 例如, 数字0用空选项值 (零长度字节序列) 表示, 数字1用数值为1的单个字节表示 (在最高有效位优先表示法中为位组合00000001). 接收者必须准备处理带有前导零字节的值.

实现注意: 发送者允许的例外行为适用于高度受限的模板化实现 (例如, 硬件实现), 这些实现在模板中使用固定大小的选项.

string (字符串): 使用UTF-8 [RFC3629] 以Net-Unicode形式 [RFC5198] 编码的Unicode字符串.

请注意, 在这里以及CoAP协议中使用UTF-8编码的所有其他地方, 意图是编码的字符串可以由CoAP协议实现直接用作不透明字节字符串并进行比较. 没有期望也不需要在CoAP实现中执行规范化 (除非从CoAP协议外部的源导入已知未规范化的Unicode字符串). 另请注意, ASCII字符串 (不使用特殊控制字符) 始终是有效的UTF-8 Net-Unicode字符串.