1. 简介 (Introduction)
受限 RESTful 环境 (Constrained RESTful Environments, CoRE) 的工作目标是以适合最受限节点 (例如 RAM 和 ROM 有限的微控制器 [RFC7228]) 和最受限网络 (例如低功耗无线个域网上的 IPv6, 即 6LoWPAN [RFC4944]) 的形式实现表述性状态转移 (Representational State Transfer, REST) 架构 [RFC7252]. CoAP 协议旨在提供类似 HTTP [RFC7230] 的 RESTful [REST] 服务, 同时降低实现复杂度和交换分组的大小, 使这些服务能够用于由高度受限节点组成的高度受限网络.
这一目标要求在若干有时相互冲突的方面保持克制:
-
降低实现复杂度, 以最小化代码大小,
-
减小消息大小, 以最小化每条消息所需的分片数量 (从而最大化消息送达概率)、所需传输功率以及对有限带宽信道的负载,
-
降低对环境的要求, 例如稳定存储、良好随机源或用户交互能力.
由于 CoAP 基于 UDP 或数据报传输层安全 (Datagram Transport Layer Security, DTLS) 等数据报传输, 在不过度分片的情况下可传输的资源表示最大大小是有限的. 此外, 并非所有资源表示都能放入受限网络的单个链路层分组中, 即使不需要 IP 层分片, 也可能导致适配层分片. 对于更大的表示, 可以使用分片 (在适配层或 IP 层) 进行传输, 直到达到底层数据报协议 (如 UDP) 的最大大小. 但是, 分片/重组过程会给较低层带来会话状态负担, 而这些状态更适合在应用层管理.
本规范定义了一对 CoAP 选项, 用于支持对资源表示的分块访问. Block 选项提供了一种最小机制, 以分块方式传输较大的资源表示. 首要目标是避免服务器需要为分块 GET 请求创建会话状态. 如果资源的创建/替换必须是原子的, 则无法完全避免为 POST/PUT 创建会话状态; 如果不需要这一属性, 在这种情况下也无需创建服务器会话状态.
分块传输通过一组交换组合实现, 每个交换都按照 CoAP 基础协议 [RFC7252] 执行. 此类组合中的每个交换都受 [RFC7252] 中规范的约束, 包括拥塞控制规范 ([RFC7252] Section 4.7) 和安全考量 ([RFC7252] Section 11; 对整个传输还适用额外安全考量, 见 Section 7). 本规范尽量减少对这些基础交换增加的约束. 但是, 并非所有 CoAP 使用变体在分块传输内部都很有用; 例如, 在 Section 2.8 的用例之外, 在分块传输中使用 Non-confirmable 请求会提高整体未送达概率. 为完全明确起见, 本规范也不会移除它严格分层其上的基础规范所施加的任何约束. 例如, 连续分组受 [RFC7252] Section 4.7 中描述的拥塞控制限制 (NSTART 限制发起交换, PROBING_RATE 限制无响应发送); 与不使用分块模式时同一客户端可向同一服务器发送/请求的流量相比, 分块传输不能发送/请求更多流量.
在某些情况下, 本规范会推荐 (RECOMMEND) 客户端"不过度延迟地"执行一系列分块传输. 这不能表述为互操作性要求, 但它是对实现质量的期望. 反过来, 也期望服务器不必特意适配那些需要相当长时间才能完成分块传输的客户端. 例如, 对于分块 GET, 如果资源在传输过程中发生变化, 后续获得块的实体标签 (entity-tag, ETag) 可能不同. 为避免快速变化资源频繁发生这种情况, 服务器可以 (MAY) 尝试为特定客户端短时间保留缓存. 这里的期望是, 这种缓存的生命周期可以保持很短, 大约为从前一个已传输块开始计算的若干个预期往返时间.
总之, 本规范为 CoAP 增加了一对可用于分块传输的 Block 选项. 使用这些选项的好处包括:
-
大于受限网络链路层分组可容纳大小的传输可以用较小块执行.
-
不会在适配层或 IP 层为分片创建难以管理的会话状态.
-
每个块的传输都会被确认, 因而可在需要时单独重传.
-
双方都可以对实际使用的块大小发表意见.
-
由此产生的交换可用分组分析工具轻松理解, 因而很便于调试.
-
如有需要, Block 选项还可以 (无需修改) 用于对资源表示中大小为 2 的幂的块提供随机访问.
不支持这些选项的 CoAP 实现通常会受到可交换表示大小的限制, 见 [RFC7252] Section 4.6. 尽管这些选项是 Critical, 服务器仍可能决定在对未包含 Block 选项的请求的响应 (Block2) 中主动开始使用它们.