CoAP(IoTプロトコル)とは?UDP上のRESTを支える仕組みとMQTTとの違いを実装視点で解説
CoAPは、メモリも電力も乏しい機器に、HTTPと同じ「要求して応答を受け取る」やり方をそのまま持たせるために作られたプロトコルです。土台はTCPではなくUDP。ヘッダはわずか4バイトで、GETやPUTといった見慣れたメソッドが並びます。この記事では、RFC 7252が定める仕組み、MQTTとの構造的な違い、Observeやブロック転送といった拡張の役割、そしてDTLSまわりの落とし穴を実装視点で整理します。見送るべき条件も代案とセットで示しました。
まとめ|CoAPを選ぶ条件とMQTTのままで足りる境界
結論から置きます。CoAPが効くのは、電池駆動や低速回線の機器に対して、サーバ側から値を取りに行きたい場合です。センサーの現在値を問い合わせる、アクチュエータへ指示を1回投げる。この形なら、常時接続を維持しないぶん消費電力が下がり、ヘッダの小ささがそのまま通信量の差になります。
逆に、機器が絶えずデータを送り続ける構成なら、MQTTのままで構いません。多数の機器の値を複数の購読側へ配る用途では、ブローカーが仲介する形のほうが素直に組めます。CoAPを持ち込むと、宛先の管理とオフライン時の取りこぼし対策を自前で書く手間が増えます。
クラウド接続の可否も先に確かめてください。主要なマネージドIoTサービスはMQTTとHTTPSを受け付ける設計で、CoAPを直接終端しません。CoAPを機器側で使うなら、現場のゲートウェイでMQTTへ翻訳する構成が前提になります。この一手間を許容できるかが、採用の分かれ目です。
CoAPの定義とRFC 7252|制約デバイス向けに作られたRESTful転送
名前だけ見ると「軽いHTTP」に思えますが、実態はHTTPの考え方を別の土台へ移植したものです。
CoAPが解こうとした課題とプロトコルスタック上の位置づけと範囲
CoAPは Constrained Application Protocol の略で、仕様は RFC 7252「The Constrained Application Protocol (CoAP)」(2014年6月・Proposed Standard)が定めています。想定する対象は、RAMが数十キロバイト、電池で数年動かす、回線は低速で損失もある、といった条件の機器です。HTTPとTCPをそのまま載せると、接続確立の往復とヘッダのサイズが電力と帯域を食い潰します。
CoAPが座るのはアプリケーション層で、下はUDPです。UDPソケットの仕組みとAPI手順を押さえておくと、何が自前で何がプロトコル側の仕事かを切り分けやすくなります。UDPは順序も到達も保証しないため、確認応答と再送はCoAP自身が持つ。TCPが担っていた最低限の信頼性を、必要な分だけ作り直した設計です。
HTTPと同じメソッドを持ちながらUDPの上で動く設計の理由
CoAPはGET・POST・PUT・DELETEの4メソッドを持ち、リソースをURIで指す。ここはRESTの6原則とREST APIの仕組みと同じ発想です。既存のWeb APIの考え方をそのまま機器へ持ち込めるため、サーバ側の学習負担が小さい。HTTPとCoAPを相互変換するプロキシの道筋も仕様に用意されています。
URIスキームは coap と coaps の2つで、デフォルトポートはUDPの5683と5684。ヘッダは4バイト固定で、バージョン、メッセージタイプ、Tokenの長さ、コード、Message IDが詰め込まれています。TCPのように接続を張らないため、1回の問い合わせが1往復で終わる。この「短い往復で完結する」性質が、電池駆動の機器では効いてきます。
メッセージ層とリクエスト層|CON・NON・ACK・RSTの使い分け
CoAPは2つの層に分かれています。ここを混ぜて理解すると、再送の設計で必ず詰まります。
CON・NON・ACK・RSTの4種類と再送タイムアウトの既定値
下側のメッセージ層は、到達確認と重複排除だけを担当します。メッセージタイプは次の4種類です。
- CON(Confirmable):到達確認を求めるメッセージ。ACKが返るまで再送する
- NON(Non-confirmable):確認を求めないメッセージ。落ちても再送しない
- ACK(Acknowledgement):CONを受け取ったことを示す応答
- RST(Reset):文脈を失った、または処理できないときに返す応答
再送の既定値はRFC 7252の4.8節にあります。ACK_TIMEOUTが2秒、ACK_RANDOM_FACTORが1.5、MAX_RETRANSMITが4。初回のタイムアウトは2秒から3秒の間で乱数によって決まり、以降は倍々に伸びて最大4回まで再送されます。同時に走らせる交換の数を制限するNSTARTは既定で1。低速回線でこの値を上げると輻輳を招きやすいため、既定のまま運用して問題が出てから触る順序が安全です。
使い分けの目安は単純です。制御指示や課金に関わる更新はCON、毎秒送る温度値のように取りこぼしても構わないデータはNON。マルチキャストで一斉に問い合わせる場合も、仕様上はNONを使うべきとされています。CONを一斉配信すると、返るACKが殺到して回線を潰しかねません。
レスポンスコードの体系とHTTPステータスとの対応関係を読む
上側のリクエスト層は、メソッドとレスポンスコードを扱います。コードは上位3ビットのクラスと下位5ビットの詳細で構成され、「2.05」「4.04」「5.00」のようにドット区切りで書く。クラス2が成功、4がクライアント側の誤り、5がサーバ側の失敗で、HTTPの200番台・400番台・500番台と対応させて読めます。
頻出するのは、GETの成功を示す2.05 Content、更新の成功を示す2.04 Changed、存在しないリソースへの4.04 Not Found です。数字の並びは違うものの意味づけの体系は同じで、既存のAPIサーバの設計を持ち込みやすい理由がここにあります。
4バイトの固定ヘッダとトークンによる要求と応答の突き合わせ方
要求と応答の対応づけには、Message IDとTokenという2つの識別子を使います。役割が違うので混同しないでください。Message IDはメッセージ層のもので、CONとACKの組を結びつけ、重複到着を検出する。Tokenはリクエスト層のもので、0〜8バイトの任意の値を要求に付け、その応答へ同じ値が返ります。
この分離が効くのは、応答をすぐ返せない場合です。サーバは先に空のACKで受領だけ伝え、処理後に別のメッセージで結果を送れる。この「分離応答」ではACKと結果のMessage IDが別物になりますが、Tokenが一致するので突き合わせられます。センサーの起動待ちなど数秒かかる実装ではこの形が要ります。
MQTTとの違い|ブローカーの有無と通信モデルによる選び分け
IoTの通信方式を検討すると、比較対象はほぼMQTTになります。両者は競合というより、向いている形が違います。
ブローカーを挟むMQTTと直接やりとりするCoAPの構造の差
MQTTは発行と購読のモデルで、送り手と受け手の間に必ずブローカーが入る。MQTTのPub/Subの仕組みとQoSの設計で扱っているとおり、機器はトピックへ発行するだけで、誰が受け取るかを知りません。1つのデータを複数の購読者へ配る構成も、オフライン中のメッセージ保持も、この仲介役があって成り立ちます。
CoAPには仲介役がいません。クライアントがサーバのURIを直接叩き、応答をその場で受け取る。機器自身がCoAPサーバとして待ち受ける構成も普通に取ります。宛先を知る必要がある代わりに、ブローカーの構築と冗長化のコストが丸ごと消えます。
| 観点 | CoAP | MQTT |
|---|---|---|
| 通信モデル | 要求と応答(REST型) | 発行と購読(Pub/Sub型) |
| 既定トランスポート | UDP(TCP版はRFC 8323) | TCP |
| 仲介役 | 不要・直接やりとり | ブローカーが必須 |
| 暗号化 | DTLSまたはOSCORE | TLS |
| 既定ポート | 5683・coapsは5684 | 1883・TLS時は8883 |
| 向く形 | 単発の値取得と制御指示 | 継続的な多点への配信 |
| クラウド直結 | 直接の終端は基本なし | AWS IoT Coreが対応 |
Observeで実現する監視とMQTTのSubscribeとの違い
「CoAPは要求と応答だから通知ができない」と誤解されがちですが、Observeという拡張で状態変化の通知を受け取れます。ただしMQTTの購読とは前提が違う。Observeはクライアントとサーバの1対1の関係の上に成り立つもので、ブローカーが持つような多対多の配信や、オフライン中のメッセージ保持は含まれません。
通知先が1つに定まる監視用途ならObserveで足りる一方、同じデータを分析基盤と監視画面と通知サービスへ同時に流したいならMQTTが素直です。値を「取りに行く」のか「配り続ける」のか、ここを先に決めてからプロトコルを選んでください。
拡張仕様の全体像|Observe・ブロック転送・OSCOREの役割
RFC 7252だけでは実務に足りません。実際の案件では、次の3つの拡張のどれかを必ず使います。
RFC 7641のObserveでプッシュ通知に近い挙動を得る
Observeは RFC 7641「Observing Resources in the Constrained Application Protocol (CoAP)」(2015年9月)で定義されます。仕組みは素直で、GETリクエストにObserveオプションを値0で付けて送ると、サーバがそのクライアントを監視登録として記憶する。以後リソースの状態が変わるたび、同じTokenを付けた追加のレスポンスが届きます。
応答に含まれるObserveオプションの値はシーケンス番号で、UDPで順序が入れ替わったときの並べ替え検出に使う。実装で気をつけるのは登録の寿命です。サーバは資源が足りなくなれば登録を破棄でき、クライアントが再起動すれば登録も消える。定期的に登録を張り直す処理がないと、通知が静かに止まった状態に気づけません。
RFC 7959のブロック転送で大きなペイロードを分割して送る
UDPのデータグラムには実質的な上限があり、大きなペイロードはIP層で分割される。制約ネットワークではこの分割が損失率を跳ね上げるため、CoAP側で分けて送る仕組みが用意されています。RFC 7959「Block-Wise Transfers in the Constrained Application Protocol (CoAP)」(2016年8月)が定めるBlock1とBlock2のオプションです。
Block1はPUTやPOSTで送る要求ペイロードの分割、Block2は応答ペイロードの分割を受け持ちます。ファームウェア更新の配信やまとまった設定値の投入では、ほぼ必ずどちらかを使う。ブロックサイズは16〜1024バイトから選べるので、経路のMTUと損失率を見て小さめから試すのが定石です。
RFC 8323のTCP版とWebSocket版が必要になる場面
企業ネットワークやモバイル網では、UDPがファイアウォールで落とされることがあります。この場合の逃げ道が RFC 8323「CoAP (Constrained Application Protocol) over TCP, TLS, and WebSockets」(2018年2月)です。信頼性のあるトランスポートの上でCoAPを話すための framing と signaling を定義し、Observeやブロック転送を接続指向の前提へ合わせ直しています。
UDPが通らない経路にCoAPを持ち込むなら、この版の対応可否をライブラリ選定の条件に入れてください。もっとも、TCPで話すならCoAPを選ぶ動機の半分は消えます。UDPの上に信頼性を載せる方向にはQUICが解いた遅延と損失の問題という別解もあり、制約が厳しい案件では方式選定そのものへ立ち返る判断もあり得ます。
セキュリティ設計|DTLSとOSCOREの選び分けと増幅攻撃対策
CoAPで最も事故が起きやすいのがここです。仕様が軽いぶん、守りは自分で設計する必要があります。
coaps(DTLS)でエンドツーエンドの機密性を確保する手順
coapsスキームは、DTLSの上でCoAPを話すことを意味します。DTLSはTLSをデータグラム向けに作り直したもので、最新版は RFC 9147「DTLS Protocol Version 1.3」(2022年4月)。TLS 1.3と同等の安全性を、順序も到達も保証されない土台の上で提供します。
制約デバイスでは、鍵の持たせ方が現実的な争点になります。証明書ベースは検証のコードサイズと計算量が重く、数十キロバイトのRAMには収まらない場合がある。事前共有鍵(PSK)方式なら軽く済みますが、機器ごとに別の鍵を配り、故障交換のたびに更新する運用が要ります。PSKを全機器で共通にすると、1台の解析で全体が破られます。
プロキシを跨ぐ構成ならOSCOREでペイロードごと暗号化する
DTLSが守るのは、隣り合う2点の間の区間だけです。CoAPの構成ではプロキシやゲートウェイを挟むことが多く、その中継点ではメッセージが一度平文に戻る。中継先を完全に信頼できないなら、区間暗号だけでは足りません。
この穴を埋めるのが RFC 8613「Object Security for Constrained RESTful Environments (OSCORE)」(2019年7月)です。COSEでCoAPメッセージ自体をアプリケーション層で保護するため、中継点を通っても中身は開かれない。ゲートウェイを他社に預ける構成では、DTLSとOSCOREを重ねる設計が現実解になります。
UDP起因の増幅攻撃とインターネットへの直結を避ける判断基準
UDPを土台にする以上、送信元IPの詐称による増幅攻撃の踏み台にされる危険がついて回ります。小さな要求に大きな応答を返す構成は、そのまま攻撃の道具になる。RFC 7252自身も送信元アドレスの検証を求めています。
実務上の判断は明快です。CoAPサーバをグローバルIPで公開しない。閉域網かVPNの内側に置き、外部との接点はゲートウェイに集約する。マルチキャストへの応答も、必要な機器だけに限定してください。IoTの仕組みと構成要素を発注側と共有するときは、この「直結させない」という前提を最初の設計図に書き込んでおくと、後からの手戻りを防げます。
実装と検証|libcoap・aiocoap・Eclipse Californiumの選択
ライブラリは言語ごとに定番が分かれます。選定を誤ると、必要な拡張が使えず設計をやり直すことになります。
言語別のライブラリ選定とファームウェア側のメモリ制約を確認する
C言語なら libcoap が広く使われ、組み込み向けにフットプリントを抑えた実装が揃っています。検証用のクライアントやサーバをPythonで立てるなら aiocoap が扱いやすく、非同期処理と相性がよい。JavaやAndroid側では Eclipse Californium が定番で、サーバ実装をまとめて書く用途に向きます。
確認項目は3つです。Observeとブロック転送に対応しているか、DTLSの鍵方式(証明書とPSK)のどちらを使えるか、RFC 8323のTCP版が要るかどうか。特にDTLSは別ライブラリとの組み合わせになることが多く、フラッシュとRAMの残量次第で選択肢が狭まります。機器のスペックを先に確定させてから決める順序が安全です。
coap-clientとWiresharkで疎通と再送を確かめる手順
疎通確認は libcoap に同梱される coap-client が手早い。まず単発のGETを投げ、レスポンスコードが2.05で返るかを見ます。
coap-client -m get coap://192.0.2.10:5683/sensors/temp
coap-client -m put -e "on" coap://192.0.2.10:5683/actuators/led
coap-client -s 60 -m get coap://192.0.2.10:5683/sensors/temp
3行目の -s は Observe の登録で、指定した秒数だけ通知を受け続けます。ここで通知が届かない場合、登録がサーバ側で破棄されているか、経路上でUDPが落とされているかのどちらかを疑ってください。
切り分けにはパケットキャプチャが要ります。WiresharkはCoAPを解析できるため、5683番のUDPに絞れば、ACKが返っているか、再送が何回走ったか、Tokenが一致しているかまで目視で追える。2秒間隔で同じMessage IDが4回並んでいれば、応答が届いていないと判断できます。
採用判断|CoAPを選ぶ条件とHTTPやMQTTへ倒す場面の見極め
ここまでの内容を、受託開発の現場で使える判断の順序に落とします。
CoAPが効く3つの条件と見送るべき場面を条件つきで言い切る
CoAPを採用してよいのは、次の3条件が揃うときです。第一に、機器が電池駆動または低速回線で、常時接続の維持がコストになること。第二に、通信の形が「サーバから値を取りに行く」または「機器へ指示を1回投げる」であること。第三に、機器とサーバが同じ閉域網の内側にあり、宛先を管理できること。
1つでも外れるなら見送ってください。電源が確保でき回線も安定しているなら、HTTPSで書いたほうが開発も運用も速い。機器が絶えずデータを吐き続ける構成ならMQTTが素直です。既存の産業機器が相手ならModbusのRTUとTCPの違いとレジスタ設計のほうが資産に合う場面もある。選ぶ理由が「軽いから」だけなら、その軽さが効く条件が揃っているかを先に確かめてください。
クラウド連携ではゲートウェイを挟んでMQTTへ変換する構成にする
クラウド側の制約は設計の初期に効いてきます。AWS公式の開発者ガイドによれば、AWS IoT Core が受け付ける機器側のプロトコルは MQTT・MQTT over WebSocket Secure・HTTPS の3つで、CoAP は列挙されていません。AWS IoT Coreの機能とMQTT接続の方法を前提にするなら、機器がCoAPで話す構成は現場側のゲートウェイで翻訳する形になります。
この構成自体は珍しくありません。センサー群とゲートウェイの間はCoAPで軽く、そこからクラウドまではMQTTで安定して、という役割分担は理にかなっています。ただし単一障害点が生まれ、変換処理の実装と監視が追加される。この運用負荷を見込んでも省電力効果が上回るかを見積もってください。
機器の選定やゲートウェイの構成まで含めて決めきれない場合は、プロトコル単体を比較しても答えは出ません。AI/IoTソリューション開発の構成を相談するほうが、現場の電源事情や既存設備の制約まで含めた形で先に片付きます。通信方式の選択は、システム全体の構成が決まったあとに従うものです。
よくある質問
CoAPの検討で挙がる質問を、実装と運用の観点から整理しました。
CoAPとMQTTはどちらを選ぶべきですか?
通信の形で決めてください。サーバ側から値を取りに行く、機器へ単発の指示を出す用途ならCoAP。多数の機器が絶えず送るデータを複数の受け手へ配る用途ならMQTTです。マネージドサービスへ直接つなぐ前提なら、MQTTのほうが手間は少なく済みます。
UDPを使うのにデータが欠けないのはなぜですか?
CoAP自身が確認応答と再送を持っているためです。Confirmable(CON)で送ればACKが返るまで再送され、既定では最大4回、初回は2秒前後の間隔で試行されます。逆にNon-confirmable(NON)で送った場合は再送されないため、落ちても構わないデータにだけ使ってください。
CoAPで機器からのプッシュ通知は実現できますか?
RFC 7641のObserveオプションで実現できます。GETに Observe を値0で付けて登録すると、以後リソースの状態が変わるたびに追加のレスポンスが届く仕組みです。ただし登録はサーバ側の判断で破棄されるため、定期的に張り直す処理を実装側で用意する必要があります。
CoAPをインターネットに直接公開しても問題ありませんか?
避けてください。UDPを土台にするため送信元IPの詐称による増幅攻撃の踏み台にされる危険があり、小さな要求に大きな応答を返す構成ほど狙われます。閉域網かVPNの内側に置き、外部との接点はゲートウェイへ集約する構成が前提です。公開が避けられない場合でも、coaps(DTLS)と送信元の検証を必ず併用します。
既存のHTTP APIをCoAPへ移行する作業量はどれくらいですか?
サーバ側だけなら小さく、機器側を含めると桁が変わります。メソッドとコードの体系が対応するため、サーバ側はリソース設計を流用でき、変換プロキシを立てる程度で済む場合もある。一方でファームウェア側はライブラリの組み込み、DTLSの鍵配布、メモリ収支の再設計が加わり、検証込みで数週間から数か月が現実的です。
関連記事
- MQTTとは?Pub/Subの仕組み・QoS・MQTT 5.0の実装からHTTPとの使い分けまで実装者向けに解説:比較対象となるIoTの定番プロトコル
- ソケット通信とは?TCP/UDPソケットの仕組み・API手順・実装の勘所を実装者向けに解説:CoAPが土台にするUDP側の実装
- RESTとは?REST APIの仕組みと6原則・SOAP/GraphQLとの違いを実装目線で解説:CoAPが写し取った要求と応答のモデル
- QUIC(通信プロトコル)とは?HTTP/3を支える仕組みとTCPとの違いを実装視点で解説:UDPの上に信頼性を載せる別解
- Modbusとは?RTUとTCPの違い・レジスタとファンクションコードを実装目線で解説:産業機器側の既存資産との接続
- AWS IoT Coreとは?機能・料金・MQTT接続方法をまとめて解説:クラウド側が受け付けるプロトコル