1. 课程导入与CoAP定位

在物联网系统中,设备通信协议的选择往往决定了整个系统的功耗、带宽占用、开发复杂度和可维护性。当我们面对的是电池供电、内存只有几十KB、网络链路可能是NB-IoT或LoRa的受限设备时,直接使用HTTP或MQTT并不总是最优解。CoAP(Constrained Application Protocol,受限应用协议)正是为这类场景设计的轻量级应用层协议。本课程以“设备通信与资源模型开发”为主线,围绕CoAP的报文交互、资源组织、观察机制、安全传输和工程实现展开,帮助你把协议知识转化为可落地的设备端与服务端代码。

为什么受限设备需要专门的协议

先看一个典型的受限设备场景:一颗基于Cortex-M0+的温湿度传感器节点,RAM约20KB,Flash约128KB,通过NB-IoT模组接入网络,每5分钟上报一次数据,使用两节AA电池供电,期望续航12个月。如果在这类设备上运行HTTP/1.1,仅TCP握手、TLS握手和HTTP头部就会消耗大量字节和能量。一个简单的GET请求,HTTP头部可能超过200字节,而CoAP可以把同样的语义压缩到几十字节以内。

CoAP的设计目标可以概括为四点:基于UDP的轻量传输、类HTTP的请求/响应语义、内建资源发现与观察机制、以及对低功耗和低带宽链路的友好性。它并不试图取代HTTP,而是在受限环境中提供一种“够用且省”的通信方式。CoAP默认使用UDP 5683端口,安全版本CoAPS使用5684端口,报文头部固定4字节,之后是Token、Options和Payload,结构紧凑。

CoAP、HTTP与MQTT的定位对比

理解CoAP的定位,最有效的方式是把它和HTTP、MQTT放在同一张坐标系里比较。HTTP是典型的“客户端主动请求、服务端响应”模型,基于TCP,头部冗长,适合浏览器和服务器之间的富文本交互。MQTT是发布/订阅模型,基于TCP,通过Broker解耦生产者和消费者,适合设备数量多、消息频率高、需要一对多分发的场景。CoAP则是“请求/响应+观察”模型,基于UDP,既支持客户端主动拉取,也支持服务端资源变化时主动推送通知。

三者的关键差异可以从传输层、通信模型、消息开销、典型适用场景四个维度来看。HTTP基于TCP,通信模型是请求/响应,消息开销大,适合Web服务和云端API;MQTT基于TCP,通信模型是发布/订阅,消息开销中等,适合大规模设备接入和消息分发;CoAP基于UDP,通信模型是请求/响应加观察,消息开销小,适合受限设备、低功耗传感网和本地资源交互。需要强调的是,CoAP并不是“UDP版的HTTP”这么简单,它通过Confirmable/Non-confirmable消息、重传机制和Block-wise传输,在UDP之上补足了可靠性能力。

CoAP / HTTP / MQTT 协议定位对比 CoAP 传输层 UDP(默认5683) 通信模型 请求/响应 + Observe 消息开销 极小(头部4字节起) 可靠性 CON重传 + Block-wise 资源发现 /.well-known/core 典型场景 受限设备、低功耗传感网 HTTP 传输层 TCP(80/443) 通信模型 请求/响应 消息开销 大(头部常超200字节) 可靠性 TCP保证 资源发现 无统一机制 典型场景 Web服务、云端API MQTT 传输层 TCP(1883/8883) 通信模型 发布/订阅(Broker) 消息开销 中等(固定头2字节起) 可靠性 QoS 0/1/2 资源发现 主题订阅 典型场景 大规模设备接入、消息分发 CoAP以UDP+资源模型为核心,在受限设备场景中兼顾轻量与语义完整

CoAP的核心角色:设备通信与资源模型

CoAP在物联网通信中扮演两个核心角色。第一个角色是“设备通信协议”,它定义了设备如何以请求/响应方式交换数据。一个CoAP请求由方法码(GET、POST、PUT、DELETE)、请求URI、可选载荷组成;响应由状态码(如2.05 Content、4.04 Not Found)和载荷组成。与HTTP不同的是,CoAP的URI以“资源”为中心,例如coap://[2001:db8::1]:5683/sensors/temperature,其中/sensors/temperature就是资源路径。

第二个角色是“资源模型载体”。在CoAP中,设备上的每一个可访问对象都被抽象为资源,资源可以是一个传感器读数、一个执行器状态、一个配置参数,甚至一个固件升级入口。资源通过URI标识,通过方法操作,通过Content-Format声明媒体类型。这种模型让设备端和服务端的接口设计变得清晰:服务端不需要知道设备内部如何实现,只需要知道有哪些资源、支持哪些方法、返回什么格式。

资源发现是CoAP资源模型的重要能力。设备可以在/.well-known/core路径下暴露资源列表,客户端通过GET请求获取。例如,一个温湿度节点可能返回:

GET coap://[2001:db8::1]:5683/.well-known/core

2.05 Content
Content-Format: application/link-format
Payload:
</sensors/temperature>;rt="temperature";if="sensor",
</sensors/humidity>;rt="humidity";if="sensor",
</config/report_interval>;rt="config";if="actuator"

这段响应说明设备暴露了三个资源:温度传感器、湿度传感器和上报间隔配置。客户端可以据此动态构建访问逻辑,而不需要硬编码资源路径。这正是CoAP资源模型的价值所在。

本课程的主线:从协议理解到资源模型开发

本课程不会停留在协议规范的逐条翻译上,而是以“设备通信与资源模型开发”为主线,把CoAP知识拆解为可实现的工程任务。你会看到如何构造和解析CoAP报文,如何设计资源路径和Content-Format,如何实现Observe机制让服务端在资源变化时收到通知,如何使用Block-wise传输处理大载荷,如何用DTLS保护CoAPS通信,以及如何在资源受限设备上裁剪协议栈。

课程中会使用一个贯穿案例:一个具备温度、湿度和LED控制能力的CoAP设备节点。温度资源/sensors/temperature支持GET和Observe,湿度资源/sensors/humidity支持GET,LED资源/actuators/led支持GET、PUT和POST。服务端可以通过/.well-known/core发现这些资源,通过Observe订阅温度变化,通过PUT控制LED开关。这个案例会随着章节推进逐步扩展,最终形成一个可运行、可测试的CoAP设备端实现。

学习建议:在进入后续章节前,先确认你手边有一个可用的CoAP调试环境。可以使用libcoap的coap-client命令行工具,也可以使用Python的aiocoap库,或者Node.js的node-coap。后续章节的示例会以命令行和代码片段两种形式给出,你可以根据自己的技术栈选择跟随方式。

关键概念速览

在正式进入协议细节之前,先建立几个关键概念的直觉。CoAP消息分为Confirmable(CON)和Non-confirmable(NON)两类。CON消息需要接收方回复ACK,如果超时未收到ACK,发送方会重传,默认重传次数为4次,初始超时时间为2秒,采用指数退避。NON消息不要求ACK,适合周期性上报等可容忍丢失的场景。Token用于匹配请求和响应,长度0到8字节,由客户端生成。Message ID用于检测重复消息和匹配ACK,长度16位。

CoAP的请求方法包括GET、POST、PUT、DELETE,语义与HTTP类似但更精简。响应码分为2.xx成功、4.xx客户端错误、5.xx服务端错误。Options用于携带URI路径、Content-Format、Max-Age、ETag等元数据,采用增量编码,进一步压缩报文长度。这些机制共同构成了CoAP在受限环境中的通信基础,也是后续章节展开实现的起点。

当你理解了CoAP的定位和资源模型,再回头看HTTP和MQTT,就会发现三者并不是竞争关系,而是面向不同约束条件的工具。CoAP适合设备侧的资源交互和低功耗通信,MQTT适合云端的大规模消息分发,HTTP适合富交互的Web服务。在实际物联网系统中,它们经常组合使用:设备通过CoAP与网关通信,网关通过MQTT将数据汇聚到云平台,云平台再通过HTTP向应用层提供API。本课程聚焦的,正是这条链路中最靠近设备的一端。