CoAP（Constrained Application Protocol，受限应用协议）是一种计算机协议，专门用于资源受限的物联网设备，具有轻量级、可靠传输和高效数据交换的特点，适用于资源受限的环境。 由于物联网设备的内存和计算能力有限，传统的 HTTP 协议在这些设备上显得过于庞大和复杂。因此，IETF 的 CoRE 工作组提出了基于 REST 架构的 CoAP 协议（ RFC 7252）。 CoAP 协议有两个不同的层：消息负载和请求/响应层。消息层处理 UDP 和异步消息，而请求/响应层基于请求/响应消息来管理请求/响应交互。CoAP 消息模型是 CoAP 的最低层，处理端点之间的 UDP 交换消息。每个 CoAP 消息都有一个唯一的 ID，这有助于检测消息重复。CoAP 协议使用两种消息：确认消息和不可确认的消息。确认消息是可靠消息，客户端可以使用这种消息确保消息将到达服务器。而不可确认的消息则不需要服务器确认。 协议特点 CoAP 协议网络传输层由 TCP 改为 UDP，以适应资源受限设备的需要。 它基于 REST 架构，这意味着服务器上的资源地址与互联网中的 URL 格式类似。客户端可以使用类似于 HTTP 的 POST、GET、PUT 和 DELETE 方法来访问服务器，这使得对 HTTP 的请求进行了简化。 CoAP 采用二进制格式，相比之下，HTTP 是文本格式，因此 CoAP 更加紧凑，可以减少传输的数据量。 CoAP 协议轻量化，最小长度仅为 4B，相比之下，一个 HTTP 头部可能达到几十个字节。 CoAP 支持可靠传输、数据重传和块传输，确保数据可靠到达。 CoAP 还支持 IP 多播，这意味着可以同时向多个设备发送请求。 CoAP 采用非长连接通信，适用于低功耗物联网场景。这与 TCP 的机制类似，对方必须确认收到消息，以实现可靠的消息传输。 消息类型 CoAP 协议有 4 种消息类型：CON、NON、ACK、RST CON：需要被确认的请求，如果 CON 请求被发送，那么对方必须做出响应。 NON：不需要被确认的请求，如果 NON 请求被发送，那么对方不必做出回应。这适用于消息会重复频繁的发送，丢包不影响正常操作。 ACK：应答消息，对应的是 CON 消息的应答。 RST：复位消息，可靠传输时候接收的消息不认识或错误时，不能回 ACK 消息，必须回 RST 消息。 消息格式 消息头 必备，固定 4 个 byte。 Ver：2 bit，版本信息，当前为 0x01。 T： 2 bit， 消息类型，包括 CON, NON, ACK, RST 这 4 种。 TKL：4 bit，token 长度， 当前支持 0 ~ 8 B 长度，其他长度保留将来扩展用。 Code：8 bit，分成前 3 bit（0 ~ 7）和后 5 bit（0 ~ 31），前 3 bit 代表类型。 0.00 Indicates an Empty message 0.01-0.31 Indicates a request 1.00-1.31 Reserved 2.00-5.31 Indicates a response. 6.00-7.31 Reserved Message ID：16 bit， 代表消息 MID，每个消息都有一个 ID ，重发的消息 MID 不变。在一次会话中 ID 总是保持不变。但在这个会话之后该 ID 会被回收利用。 token 可选，用于将响应与请求匹配。 token 值为 0 到 8 字节的序列。每个请求都带有一个客户端生成的 token, 服务器在任何结果响应中都必须对其进行回应。token 类似消息 ID，用以标记消息的唯一性。token 还是消息安全性的一个设置，使用全 8 字节的随机数，使伪造的报文无法获得验证通过。标记是 ID 的另一种表现。 option 可选，0 个或者多个。请求消息与回应消息都可以有零到多个 options。 主要用于描述请求或者响应对应的各个属性，类似参数或者特征描述，比如是否用到代理服务器，目的主机的端口等。CoAP 选项类似于 HTTP 请求头，它包括 CoAP 消息本身，例如 CoAP 端口号，CoAP 主机和 CoAP 查询字符串等。 payload 可选。实际携带数据内容， 若有， 前面加 payload 标识符 “0xFF”，如果没有 payload 标识符，那么就代表这是一个 0 长度的 payload。如果存在 payload 标识符但其后跟随的是 0 长度的 payload，那么必须当作消息格式错误处理。 请求方法（requests） 0.01 GET 方法——用于获得某资源 0.02 POST 方法——用于创建某资源 0.03 PUT 方法——用于更新某资源 0.04 DELETE 方法——用于删除某资源 URI 一个 CoAP 资源可以被一个 URI（Uniform Resource Identifier，统一资源标识符）所描述，例如一个设备可以测量温度，那么这个温度传感器的 URI 被描述为：coap://machine.address/sensors/temperature CoAP 的 URL 和 HTTP 的有很相似的地方，开头是 “coap” 对应 “http” 或者 “coaps” 对应 “https”。coap 默认端口 UDP 5683，coaps 默认端口是 UDP 5684。默认端口号可以省略。 规则与 http 的 URL 是一样的，比如不区分大小写等。 注：URL（Uniform Resource Locator，统一资源定位器）是一种特定的 URI，这种 URI 还含有如何获取资源的信息（例如 http、coap 等）。 安全性 CoAP 的安全性是用 DTLS 加密实现的。DTLS 的实现需要的资源和带宽较多，如果是资源非常少的终端和极有限的带宽下可能会跑不起来。DTLS 仅仅在单播情况下适用。 通信过程 上面以 GET 流程为例子，有没有发现，其实跟 HTTP 相类似。 Client 发起请求，类型是 CON，0.01 代表 GET 请求，MID 是请求消息 ID，URI-Path:temperature 代表请求温度。例如： coap://example.com:5683/~sensors/temperature Server 收到请求后，就会返回应答 2.05, MID 保持不变，并且返回具体参数 payload 温度 22.3 C 双向收发 基于消息的双向通信（M2M），CoAP Client 与 CoAP Server 双方都可以独立向对方发送请求。双方可当 client 或者 server 角色。传统的 HTTP 协议是主机与 web 服务器之间是单向通信的（用 websocket 除外）。而 CoAP 系统中 CoAP Client 与CoAP Server 是可以双向通信，双方都可以主动向对方发送请求。这也是 CoAP 协议解决物联网场景问题的关键所在。 订阅与发布 MQTT 协议是基于订阅与发布模型的，CoAP 通过扩展协议方式也简单的实现了订阅与发布模型。 当一个客户端需要定期去查询服务器端某个资源的最新状态时，订阅与发布模型就非常有用，不用这个模型，客户端就要周期的不断发送请求到服务器端。 模型框架： 关键概念： 主题 Subject： 代表 CoAP 的某个资源 观察者 Observer：代表对某个 CoAP 资源感兴趣的客户端 登记 Registration： 观察者需要向服务器登记感兴趣的主题 通知 Notification：当观察者感兴趣的主题发生内容变化时，服务器主动通知到观察者 观察协议在 CoAP 基础协议上增加了 1 个 Observe option， 其值为整数，通过该 options 来实现订阅与发布模型管理 在 GET 请求消息里面： oberser value 为 0： 代表向服务器端订阅一个主题。 oberser value 为 1： 代表向服务器端移除一个已订阅主题。 在 notification 消息里面： oberser value 代表 主题发生变化时，检测到顺序，以便客户端可以知道状态变化的先后。 客户端向服务器端登记感兴趣的主题 /temperature 当 temperature 发生状态改变时，服务器端主动通知到客户端。 客户端根据 token，就可以与之前订阅主题关联起来，以此确定是哪个主题订阅的。 一个 CoAP Client 可以分次向 CoAP Server 订阅多个资源主题。 一个 CoAP Server 上的主题可以被多个观察者（CoAP Client）订阅。 这样就通过了 CoAP Server 实现了 CoAP Client 之间直接数据转发通信。 可以通过灵活设计服务器上的资源链接，来实现对某个主题的条件订阅（类似触发器或者阀值等）。 比如订阅主题是: coap://server/temperature/critical?above=42 当温度超过 42，CoAP Server 需要发送通知。