Qt CoAP 概述

提供对CoAP协议和Qt CoAP模块的深入了解。

受限应用协议(CoAP)是一种物联网协议,专门设计用于在受限网络中的受限设备(如微控制器)之间进行M2M数据交换。

CoAP的交互模型类似于HTTP的客户端/服务器模型,但与HTTP不同的是,它使用面向数据报的无连接传输,如UDP,这导致非常低的开销,并允许使用UDP广播和组播进行寻址。同时,它提供了轻量级的可靠性机制和安全性。

Qt CoAP 实现了 CoAP 的客户端。默认情况下,传输层使用 QUdpSocket 和 QDtls 进行安全保护。通过实现 QCoapConnection 接口,可以使用替代的传输方式。

消息模型

CoAP消息模型基于端点之间的消息交换:客户端向服务器发出请求;服务器发送回响应。客户端可以对资源进行GETPUTPOSTDELETE操作。他们还可以通过发出发现请求来发现服务器上的资源,或者在本地网络中通过发出多播发现请求来发现资源。还可以通过观察请求订阅资源。

传输的可靠性通过将消息标记为可确认(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 Link Format表示。

专门的 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);

对于Observe请求,您可以使用notified信号来处理来自CoAP服务器的通知。

分块传输

由于CoAP基于UDP等数据报传输,因此在没有分片导致问题的情况下,资源表示的大小是有限制的。Qt CoAP支持在资源表示大于单个CoAP数据报的有效负载时进行分块传输。

安全性

为CoAP定义了以下安全模式:

  • 预共享密钥 - 在这种模式下,客户端必须向服务器发送其身份和预共享密钥。

  • 原始公钥 - 客户端拥有一个没有证书的非对称密钥对(原始公钥)。客户端还有一个从公钥计算出的身份以及它可以通信的节点身份列表。Qt CoAP 尚未实现此模式。

  • 证书 - 客户端拥有一个带有X.509证书的非对称密钥对,该证书由某个共同的信任根签名。

由于CoAP设计为基于UDP的协议,Qt CoAP模块实现了基于UDP的Datagram 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);