簡易CoAPクライアント
CoAPサーバーと通信するアプリケーションの作成。

「シンプルなCoAPクライアント」では、CoAPメッセージの送受信を行う最小限のCoAPクライアントアプリケーションの作成方法を解説します。
サンプルを実行する
サンプルは次の場所から実行できます。
- Qt Creator
Welcome モードを開き、Examples からこのサンプルを選択します。詳細については、Qt Creator の「チュートリアル:ビルドと実行」を参照してください。
- Qt Extension for Visual Studio Code
Command Palette から `Qt: Open Qt examples ` コマンドを実行し、リストからこのサンプルを選択します。詳細については、Qt Extension for Visual Studio Code の「チュートリアル:ビルドと実行」を参照してください。
CoAPサーバーの設定
アプリケーションを使用するには、CoAPサーバーを指定する必要があります。以下のオプションがあります。
coap://coap.meにある CoAP テストサーバーを使用します。- libcoap、FreeCoAP、またはその他の CoAP サーバー実装を使用して CoAP サーバーを作成します。
- CoAPの機能の大部分をサポートしているCaliforniumplugtestサーバーを使用します。手動でビルドすることも、plugtestサーバーをビルドして起動する既製のDockerイメージを使用することもできます。Dockerベースのサーバーを使用するための手順を以下に説明します。
Docker ベースのテストサーバーの使用
次のコマンドを実行すると、Docker Hub から CoAP サーバー用の Docker コンテナを取得し、起動します:
docker run --name coap-test-server -d --rm -p 5683:5683/udp -p 5684:5684/udp tqtc/coap-californium-test-server:3.8.0Docker コンテナの IP アドレスを確認するには、まず `docker ps` を実行してコンテナ ID を取得します。これにより、次のような出力が表示されます:
$ docker ps
CONTAINER ID IMAGE
5e46502df88f tqtc/coap-californium-test-server:3.8.0その後、次のコマンドで IP アドレスを取得できます:
docker inspect <container_id> | grep IPAddress例:
$ docker inspect 5e46502df88f | grep IPAddress
...
"IPAddress": "172.17.0.2",
...取得したIPアドレスのポート5683(非セキュア)および5684(セキュア)で、CoAPテストサーバーにアクセスできます。
使用後に Docker コンテナを終了するには、次のコマンドを使用します:
docker stop <container_id>ここで使用する `<container_id> ` は、`docker ps ` コマンドで取得したものと同じです。
クライアントの作成
まず、QCoapClient クラスを使用して CoAP クライアントを作成します。次に、CoAP の応答を受信したときやリクエストが失敗したときに通知を受け取れるよう、そのシグナルを接続する必要があります:
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
m_client = new QCoapClient(QtCoap::SecurityMode::NoSecurity, this);
connect(m_client, &QCoapClient::finished, this, &MainWindow::onFinished);
connect(m_client, &QCoapClient::error, this, &MainWindow::onError);
...リクエストの送信
CoAPリクエストの作成には、QCoapRequest クラスを使用します。このクラスは、CoAPフレームを構築するためのメソッドを提供しています。
void MainWindow::on_runButton_clicked()
{
const auto msgType = ui->msgTypeCheckBox->isChecked() ? QCoapMessage::Type::Confirmable
: QCoapMessage::Type::NonConfirmable;
QUrl url;
url.setHost(tryToResolveHostName(ui->hostComboBox->currentText()));
url.setPort(ui->portSpinBox->value());
url.setPath(ui->resourceComboBox->currentText());
QCoapRequest request(url, msgType);
for (const auto &option : std::as_const(m_options))
request.addOption(option);
...この例では、URLやメッセージタイプを設定し、リクエストにオプションを追加しています。ペイロード、メッセージID、トークンなどを設定することも可能ですが、ここではデフォルト値を使用しています。なお、デフォルトでは、メッセージIDとトークンはランダムに生成されます。
選択したリクエストメソッドに基づき、GET 、PUT 、POST 、またはDELETE のリクエストをサーバーに送信します。
...
switch (method) {
case QtCoap::Method::Get:
m_client->get(request);
break;
case QtCoap::Method::Put:
m_client->put(request, m_currentData);
break;
case QtCoap::Method::Post:
m_client->post(request, m_currentData);
break;
case QtCoap::Method::Delete:
m_client->deleteResource(request);
break;
default:
break;
}
...PUT およびPOST リクエストの場合、リクエストのペイロードとしてm_currentData も追加します。
サーバーのコンテンツを閲覧し、サーバー上で利用可能なリソースを検出するには、ディスカバリーリクエストを使用します:
void MainWindow::on_discoverButton_clicked()
{
...
QCoapResourceDiscoveryReply *discoverReply =
m_client->discover(url, ui->discoveryPathEdit->text());
if (discoverReply) {
connect(discoverReply, &QCoapResourceDiscoveryReply::discovered,
this, &MainWindow::onDiscovered);
...注: ディスカバリーリクエストの応答を保持するために、QCoapReply クラスの代わりに QCoapResourceDiscoveryReply を使用します。これにはQCoapResourceDiscoveryReply::discovered シグナルがあり、検出された QCoapResources のリストを返します。
サーバー上にオブザーバブルなリソース(つまり、リソースタイプが `obs` であるもの)が存在する場合、observeリクエストを実行することで、そのリソースの更新情報を購読できます:
void MainWindow::on_observeButton_clicked()
{
...
QCoapReply *observeReply = m_client->observe(url);
...
connect(observeReply, &QCoapReply::notified, this, &MainWindow::onNotified);
...クライアントは、cancelObserveButton のclicked() シグナルを処理することで、リソースのオブザーベーションを解除できます:
...
connect(ui->cancelObserveButton, &QPushButton::clicked, this, [this, url]() {
m_client->cancelObserve(url);
ui->cancelObserveButton->setEnabled(false);
});サーバーからの応答は UI に表示されます:
void MainWindow::addMessage(const QString &message, bool isError)
{
const QString content = "--------------- %1 ---------------\n%2\n\n"_L1
.arg(QDateTime::currentDateTime().toString(), message);
ui->textEdit->setTextColor(isError ? Qt::red : Qt::black);
ui->textEdit->insertPlainText(content);
ui->textEdit->ensureCursorVisible();
}
void MainWindow::onFinished(QCoapReply *reply)
{
if (reply->errorReceived() == QtCoap::Error::Ok)
addMessage(reply->message().payload());
}
static QString errorMessage(QtCoap::Error errorCode)
{
const auto error = QMetaEnum::fromType<QtCoap::Error>().valueToKey(static_cast<int>(errorCode));
return MainWindow::tr("Request failed with error: %1\n").arg(error);
}
void MainWindow::onError(QCoapReply *reply, QtCoap::Error error)
{
const auto errorCode = reply ? reply->errorReceived() : error;
addMessage(errorMessage(errorCode), true);
}
void MainWindow::onDiscovered(QCoapResourceDiscoveryReply *reply, QList<QCoapResource> resources)
{
if (reply->errorReceived() != QtCoap::Error::Ok)
return;
QString message;
for (const auto &resource : std::as_const(resources)) {
ui->resourceComboBox->addItem(resource.path());
message += tr("Discovered resource: \"%1\" on path %2\n")
.arg(resource.title(), resource.path());
}
addMessage(message);
}
void MainWindow::onNotified(QCoapReply *reply, const QCoapMessage &message)
{
if (reply->errorReceived() == QtCoap::Error::Ok) {
addMessage(tr("Received observe notification with payload: %1")
.arg(QString::fromUtf8(message.payload())));
}
}
static QString tryToResolveHostName(const QString hostName)
{
const auto hostInfo = QHostInfo::fromName(hostName);
if (!hostInfo.addresses().empty())
return hostInfo.addresses().first().toString();
return hostName;
}ファイル:
© 2026 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.