Skip to main content

2. Constrained Application Protocol (受限应用协议)

CoAP的交互模型类似于HTTP的客户端/服务器模型. 然而, 机器对机器交互通常导致CoAP实现同时充当客户端和服务器角色. CoAP请求等同于HTTP请求, 由客户端发送以请求对服务器上的资源 (由URI标识) 执行操作 (使用方法码, Method Code). 然后服务器发送带有响应码 (Response Code) 的响应; 此响应可能包括资源表示.

与HTTP不同, CoAP通过面向数据报的传输 (例如UDP) 异步处理这些交换. 这在逻辑上使用支持可选可靠性 (具有指数退避) 的消息层来完成. CoAP定义了四种类型的消息: 可确认 (Confirmable), 不可确认 (Non-confirmable), 确认 (Acknowledgement), 重置 (Reset). 其中一些消息中包含的方法码和响应码使它们携带请求或响应. 四种类型消息的基本交换与请求/响应交互有些正交; 请求可以在可确认和不可确认消息中携带, 响应也可以在这些消息中携带, 也可以在确认消息中捎带.

可以将CoAP在逻辑上视为使用两层方法, 一层是用于处理UDP和交互异步性的CoAP消息层, 另一层是使用方法码和响应码的请求/响应交互 (见图1). 然而, CoAP是单个协议, 消息传递和请求/响应只是CoAP头部的特性.

                    +----------------------+
| Application |
+----------------------+
+----------------------+ \
| Requests/Responses | |
|----------------------| | CoAP
| Messages | |
+----------------------+ /
+----------------------+
| UDP |
+----------------------+

图 1: CoAP的抽象分层

2.1. Messaging Model (消息模型)

CoAP消息模型基于端点之间通过UDP交换消息.

CoAP使用短的固定长度二进制头部 (4字节), 后面可能跟随紧凑的二进制选项和有效载荷. 此消息格式由请求和响应共享. CoAP消息格式在第3节中规定. 每条消息包含一个消息ID (Message ID), 用于检测重复和可选的可靠性. (消息ID很紧凑; 其16位大小使得使用默认协议参数时每秒从一个端点到另一个端点最多可以发送约250条消息.)

可靠性通过将消息标记为可确认 (CON) 来提供. 可确认消息使用默认超时和重传之间的指数退避进行重传, 直到接收者从相应端点发送具有相同消息ID (在此示例中为0x7d34) 的确认消息 (ACK); 见图2. 当接收者根本无法处理可确认消息 (即, 甚至无法提供适当的错误响应) 时, 它会用重置消息 (RST) 而不是确认 (ACK) 来回复.

                    Client              Server
| |
| CON [0x7d34] |
+----------------->|
| |
| ACK [0x7d34] |
|<-----------------+
| |

图 2: 可靠的消息传输

不需要可靠传输的消息 (例如, 来自传感器数据流的每个单独测量) 可以作为不可确认消息 (NON) 发送. 这些消息不被确认, 但仍然具有用于重复检测的消息ID (在此示例中为0x01a0); 见图3. 当接收者无法处理不可确认消息时, 它可以用重置消息 (RST) 回复.

                    Client              Server
| |
| NON [0x01a0] |
+----------------->|
| |

图 3: 不可靠的消息传输

有关CoAP消息的详细信息, 请参见第4节.

由于CoAP运行在UDP上, 它也支持使用组播IP目标地址, 从而启用组播CoAP请求. 第8节讨论了使用组播地址正确使用CoAP消息以及避免响应拥塞的预防措施.

第9节为CoAP定义了几种安全模式, 从无安全性到基于证书的安全性. 本文档规定了绑定到DTLS以保护协议; [IPsec-CoAP] 中讨论了将IPsec与CoAP一起使用.

2.2. Request/Response Model (请求/响应模型)

CoAP请求和响应语义在CoAP消息中携带, 其中分别包含方法码或响应码. 可选 (或默认) 的请求和响应信息 (例如URI和有效载荷媒体类型) 作为CoAP选项携带. Token用于将响应与请求匹配, 独立于底层消息 (第5.3节). (请注意, Token是与消息ID分离的概念.)

请求在可确认 (CON) 或不可确认 (NON) 消息中携带, 如果立即可用, 对可确认消息中携带的请求的响应在结果确认 (ACK) 消息中携带. 这称为捎带响应 (piggybacked response), 在第5.2.1节中详细说明. (无需单独确认捎带响应, 因为如果携带捎带响应的确认消息丢失, 客户端将重传请求.) 图4显示了两个基本GET请求与捎带响应的示例, 一个成功, 一个导致4.04 (Not Found) 响应.

    Client              Server       Client              Server
| | | |
| CON [0xbc90] | | CON [0xbc91] |
| GET /temperature | | GET /temperature |
| (Token 0x71) | | (Token 0x72) |
+----------------->| +----------------->|
| | | |
| ACK [0xbc90] | | ACK [0xbc91] |
| 2.05 Content | | 4.04 Not Found |
| (Token 0x71) | | (Token 0x72) |
| "22.5 C" | | "Not found" |
|<-----------------+ |<-----------------+
| | | |

图 4: 两个带有捎带响应的GET请求

如果服务器无法立即响应可确认消息中携带的请求, 它只是用空确认消息响应, 以便客户端可以停止重传请求. 当响应准备就绪时, 服务器在新的可确认消息中发送它 (然后需要客户端确认). 这称为"分离响应 (separate response)", 如图5所示, 并在第5.2.2节中更详细地描述.

                    Client              Server
| |
| CON [0x7a10] |
| GET /temperature |
| (Token 0x73) |
+----------------->|
| |
| ACK [0x7a10] |
|<-----------------+
| |
... Time Passes ...
| |
| CON [0x23bb] |
| 2.05 Content |
| (Token 0x73) |
| "22.5 C" |
|<-----------------+
| |
| ACK [0x23bb] |
+----------------->|
| |

图 5: 带有分离响应的GET请求

如果请求在不可确认消息中发送, 则使用新的不可确认消息发送响应, 尽管服务器可以改为发送可确认消息. 这种类型的交换如图6所示.

                    Client              Server
| |
| NON [0x7a11] |
| GET /temperature |
| (Token 0x74) |
+----------------->|
| |
| NON [0x23bc] |
| 2.05 Content |
| (Token 0x74) |
| "22.5 C" |
|<-----------------+
| |

图 6: 在不可确认消息中携带的请求和响应

CoAP以类似于HTTP的方式使用GET, PUT, POST和DELETE方法, 语义在第5.8节中规定. (请注意, CoAP方法的详细语义"几乎但不完全不同于" [HHGTTG] HTTP方法的语义: 从HTTP经验中获得的直觉通常确实适用, 但存在足够的差异, 使得阅读本规范是值得的.)

可以在单独的规范中将基本四种方法之外的方法添加到CoAP. 新方法不一定必须成对使用请求和响应. 即使对于现有方法, 单个请求也可能产生多个响应, 例如, 对于组播请求 (第8节) 或使用观察选项 [OBSERVE].

服务器中的URI支持得到简化, 因为客户端已经解析了URI并将其拆分为主机, 端口, 路径和查询组件, 利用默认值以提高效率. 响应码与HTTP状态码的一小部分相关, 并添加了一些CoAP特定的代码, 如第5.9节中所定义.

2.3. Intermediaries and Caching (中介和缓存)

该协议支持缓存响应以有效地满足请求. 使用CoAP响应携带的新鲜度和有效性信息启用简单缓存. 缓存可以位于端点或中介中. 缓存功能在第5.6节中规定.

代理在受限网络中很有用, 原因有多种, 包括限制网络流量, 提高性能, 访问休眠设备的资源以及出于安全原因. 协议中支持代表另一个CoAP端点代理请求. 使用代理时, 要请求的资源的URI包含在请求中, 而目标IP地址设置为代理的地址. 有关代理功能的更多信息, 请参见第5.7节.

由于CoAP是根据REST架构 [REST] 设计的, 因此表现出类似于HTTP协议的功能, 因此从CoAP映射到HTTP以及从HTTP映射到CoAP非常简单. 这种映射可用于使用CoAP实现HTTP REST接口或在HTTP和CoAP之间进行转换. 这种转换可以由跨协议代理 ("跨代理") 执行, 它将方法或响应码, 媒体类型和选项转换为相应的HTTP特性. 第10节提供了有关HTTP映射的更多详细信息.

2.4. Resource Discovery (资源发现)

资源发现对于机器对机器交互很重要, 并且使用第7节中讨论的CoRE链接格式 [RFC6690] 来支持.