Qt CoAP 概述#
深入了解 CoAP 协议和 Qt CoAP 模块。
受限应用协议(CoAP)是一种专为受限网络(如微控制器等)之间的 M2M 数据交换而设计的物联网协议。
CoAP 的交互模式类似于 HTTP 的客户端/服务器模型,但与 HTTP 不同,它使用基于数据报的无连接传输,如 UDP,这导致非常低的开销,并允许使用 UDP 广播和多播进行寻址。同时,它还提供了轻量级的可靠性和安全机制。
Qt CoAP 实现了 CoAP 的客户端功能。默认情况下,传输层使用 QUdpSocket 和 QDtls 进行安全通信。可以通过实现 QCoapConnection 接口使用替代传输。
消息模型#
CoAP 消息模型基于端点之间的消息交换:客户端向服务器发送请求;服务器发送响应。客户端可以获取资源(GET)、设置资源(PUT)、创建资源(POST)和删除资源(DELETE)。它们还可以通过发送发现请求来在服务器上查找资源,或在本地网络中,通过发送多播发现请求。还可以通过观察请求订阅资源。
通过标记消息为确认(CON)实现传输的可靠性。可确认消息仅在默认超时和重传之间的指数退避期间重新传输,直到接收方发送确认(ACK)消息。如果接收方无法处理可确认消息,则回复重置(RST)消息而不是确认。
不需要可靠传输的消息可以作为一个非确认(NON)消息发送。
使用 Qt CoAP API#
客户端与 CoAP 服务器的通信是通过 QCoapClient
类进行的。它包含发送不同 CoAP 请求的方法以及当收到的响应触发时发出的信号。使用 QCoapRequest
类来创建 CoAP 请求。来自服务器的响应在一个 QCoapReply
对象中返回。例如
QCoapClient *client = new QCoapClient(); connect(client, &QCoapClient::finished, this, &MyClass::onFinished); connect(client, &QCoapClient::error, this, &MyClass::onError); QCoapRequest request(QUrl("coap://127.0.0.1/test"), QCoapMessage::Confirmable); client->get(request); client->put(request, QByteArray("payload"));
支持的功能#
资源发现#
CoAP 发现请求用于查询端点或整个网络中可用的资源。这对于没有人类参与的 M2M 应用程序非常重要。例如,在家庭或建筑自动化中,需要本地客户端和服务器在无需人类干预的情况下相互发现和交互。资源发现使客户端能够在网络中了解到可用的端点。
Qt CoAP 支持对单个端点和多播组的发现请求。例如,对 /.well-known/core
的发现请求,这是默认的资源发现入口点,可能会返回类似
RES: 2.05 Content </sensors/temp>;rt="temperature-c";if="sensor";obs, </sensors/light>;rt="light-lux";if="sensor", </firmware/v2.1>;rt="firmware";sz=262144
表示该网络中有温度和光传感器资源以及固件资源。回复以 CoRE 链接格式 表示。
使用专门的 QCoapResourceDiscoveryReply
类来获取发现回复
// This will make a multicast discovery request to the CoAP IPv4 multicast group. QCoapResourceDiscoveryReply *discoverReply = client->discover(); connect(discoverReply, &QCoapResourceDiscoveryReply::discovered, this, &MyClass::onDiscovered);
discovered
将返回在网络中找到的 CoAP 资源列表。
资源观察#
使用观察请求来接收资源的自动服务器通知。客户端通过向资源发送观察请求成为可观察资源的观察者。例如,上述示例中的温度传感器是可观察的,因为它具有 obs
属性。因此,客户端可以通过向其发送观察请求来订阅温度更新。
以下示例代码展示了如何使用 Qt CoAP 发送观察请求
QCoapReply *reply = client->observe(QUrl("127.0.0.1/temp")); connect(reply, &QCoapReply::notified, this, &MyClass::onNotified);
对于观察请求特别地,您可以使用 notified
信号来处理来自 CoAP 服务器的通知。
分块传输#
由于 CoAP 基于 UDP 等数据报传输,对于单一的 CoAP 数据报可以传输而不会引起碎片化问题的资源表示的大小存在限制。Qt CoAP 支持分块传输,用于资源表示大于单个 CoAP 数据报有效负载可以舒适地传输的情况。
安全性#
以下安全性模式被定义用于 CoAP
预共享密钥 - 在此模式下,客户端必须将其身份和预共享密钥发送到服务器。
原始公钥 - 客户端有一对非对称密钥,没有证书(原始公钥)。客户端还有一个由公钥计算得出的身份,以及它可以进行通信的节点的身份列表。Qt CoAP 尚未实现此模式。
证书 - 客户端有一对带有由某些常用信任根签名的 X.509 证书的非对称密钥。
由于 CoAP 被设计成基于 UDP 的协议,Qt CoAP 模块通过在 UDP 上实现基于数据报 TLS(DTLS)来执行安全性。然而,如上所述,可以提供具有其他安全类型的自定义传输。
为了保护 CoAP 客户端,在创建客户端时应指定支持的安全性模式之一
QCoapClient *client = new QCoapClient(this, QtCoap::PreSharedKey);
使用 QCoapSecurityConfiguration
类来指定安全参数。例如,在预共享密钥模式下,可以使用以下示例代码
QCoapSecurityConfiguration config; config.setPreSharedKey("secretPSK"); config.setIdentity("Client_identity"); client->setSecurityConfiguration(config);
以及在证书模式下
QCoapClient *client = new QCoapClient(this, QtCoap::Certificate); QList<QSslCertificate> localCertificates, caCertificates; QCoapPrivateKey key; // Initialize the key and certificates QCoapSecurityConfiguration config; config.setLocalCertificateChain(localCertificates); config.setCaCertificates(caCertificates) config.setPrivateKey(key); client->setSecurityConfiguration(config);