9
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【MQTT通信】SocketDebuggerでTCPペイロードを完全解説 ─ CONNECT/PUB/SUBを手作業で体験してみた⚡

Last updated at Posted at 2025-09-11

1. はじめに

前回の記事「新人研修や自習にも!3分でサクッと理解するMQTT入門 ─ HTTPとの違いとIoT活用💡」では、MQTTの概念やHTTPとの違いをイメージでつかむことを目指しました。

今回はその続きとして、いよいよ 自分のPC上でSocketDebuggerを使い、MQTT通信を手で動かしてみる 実践編です。
TCPペイロードに正しいMQTTフォーマットを手作業で配置し、CONNECT/SUBSCRIBE/PUBLISH の一連の流れを体験します。

image.png

手作業なので実用性は低いですが、そのぶん MQTTのプロトコル構造をバイト単位でじっくり理解できる 貴重な機会です。
「プロトコルを深く理解したい」「通信の中身を直接見てみたい」という方にぴったり。新人研修や自習として、ぜひ挑戦してみてください!

2. 環境準備

まずは実験環境を整えましょう。本記事では 自分のPC上でSocketDebuggerを2つ起動 して、1つを送信側(Publisher)、もう1つを受信側(Subscriber)として使用します。

必要なもの

  • SocketDebugger(最新版をインストール)
  • インターネット接続(無料MQTTブローカに接続するため)
    例:test.mosquitto.org ポート 1883
  • 基本的な TCP/UDP通信の知識(理解がスムーズになります)

接続のイメージ

以下のように構成します:
image.png

  • SocketDebugger①(Publisher)
    ・MQTTパケットを手作業で作成
    ・MQTTブローカに CONNECT → PUBLISH を送信
  • SocketDebugger②(Subscriber)
    ・MQTTパケットを手作業で作成
    ・MQTTブローカに CONNECT → SUBSCRIBE を送信
    ・Publisherから届いた PUBLISH メッセージを受信

ここでのポイント

  • 両方のSocketDebuggerで手作業によるパケットを作ることで、MQTTの通信の流れをバイト単位で理解できます
  • 同じPCでも2つのSocketDebuggerを起動可能です
  • MQTTブローカは無料で使えるものを使用するので、すぐに実験を始められます

これで、手作業でのMQTT通信実験の準備 は完了です。

3. MQTTパケット構造の解説

MQTT通信を手作業で体験するためには、まず 各パケットの構造 を理解する必要があります。
本章では CONNECT / SUBSCRIBE / PUBLISH の3種類のパケットを例に、Hexペイロードをバイト単位で解説します。

3.1 MQTTバージョンについて

MQTTにはいくつかのバージョンがありますが、本記事では MQTT 3.1.1(プロトコルレベル4) を使用します。

  • 理由
    • 無料MQTTブローカでも標準的に対応している
    • CONNECTパケットがシンプルで、手作業でバイトを組み立てやすい
    • 初心者でも理解しやすく、SocketDebuggerでの実践に最適
  • CONNECTパケットで指定する内容
    • プロトコル名:MQTT
    • プロトコルレベル:0x04

注意

  • MQTT 5.0ではプロパティなどが追加されるため、手作業での解析や送信は難易度が高くなります
  • 実践編としては、まずMQTT 3.1.1で理解を深めることをおすすめします

3.2 CONNECTパケット

CONNECTパケットは、クライアントがMQTTブローカに接続する際、最初に送るパケットです。

CONNECTパケット全体フォーマット
セクション 項目名 サイズ 内容 備考
Fixed Header パケットタイプ & フラグ 1バイト 0x10 CONNECTパケットは常にこの値
残りの長さ(Remaining Length) 1〜4バイト 例:0xC8 0x01(200バイト) Variable Header + Payloadの合計サイズ
Variable Header プロトコル名の長さ 2バイト 0x00 0x04 常に4(MQTT)
プロトコル名 4バイト 0x4D 0x51 0x54 0x54 "MQTT"(固定)
プロトコルレベル 1バイト 0x04 MQTT v3.1.1
接続フラグ 1バイト 例:0xC2 認証やWillメッセージの有無を示す
キープアライブ 2バイト 例:0x00 0x3C(60秒) 通信がないときのタイムアウト時間
Payload クライアントIDの長さ 2バイト 例:0x00 0x04 IDの文字数
クライアントID Nバイト 例:0x74 0x65 0x73 0x74 "test"など
Will Topic(任意) 2 + Nバイト 省略可 WillフラグがONのときのみ
Will Message(任意) 2 + Nバイト 省略可 WillフラグがONのときのみ
ユーザー名(任意) 2 + Nバイト 省略可 ユーザー名フラグがONのときのみ
パスワード(任意) 2 + Nバイト 省略可 パスワードフラグがONのときのみ
接続フラグ(Connect Flags)の意味
ビット位置 名前 値が1のときの意味 備考
7 ユーザー名フラグ ユーザー名がPayloadに含まれる 認証に使用
6 パスワードフラグ パスワードがPayloadに含まれる 認証に使用
5 Will Retain Willメッセージを保持する Will QoSと併用
4〜3 Will QoS WillメッセージのQoSレベル(0〜2) 2ビットで表現
2 Willフラグ Willメッセージを送信する TopicとMessageがPayloadに含まれる
1 Clean Session セッションを新規に開始する 前回の状態を保持しない
0 予約 常に0 使用禁止(仕様で定義)

3.2.1 CONNACKパケット

CONNACKパケットは、クライアントがCONNECTパケットを送った後、MQTTブローカ(サーバー側)が応答として返すパケットです。

CONNACKパケット全体フォーマット
セクション 項目名 サイズ 内容 備考
Fixed Header パケットタイプ & フラグ 1バイト 0x20 CONNACKパケットは常にこの値
残りの長さ(Remaining Length) 1バイト 0x02 Variable Headerのサイズ(2バイト)
Variable Header 接続確認フラグ(Session Present) 1バイト 0x00 または 0x01 Clean SessionがOFFのときにセッションが残っているか
接続応答コード(Connect Return Code) 1バイト 0x00〜0x05 接続結果(成功・失敗の理由)
接続応答コード(Connect Return Code)の意味
コード 意味 説明
0x00 接続成功 正常に接続された
0x01 不正なプロトコルバージョン Protocol Levelがサポートされていない
0x02 識別子拒否 Client IDが不正または重複
0x03 サーバー利用不可 MQTTブローカが一時的に利用できない
0x04 認証情報不正 ユーザー名またはパスワードが不正
0x05 認証拒否 認証に失敗した

3.3 SUBSCRIBEパケット

SUBSCRIBEパケットは、クライアントがMQTTブローカに「このトピックのメッセージを受け取りたい」とリクエストするために送るパケットです。

SUBSCRIBEパケット全体フォーマット
セクション 項目名 サイズ 内容 備考
Fixed Header パケットタイプ & フラグ 1バイト 0x82 SUBSCRIBEはタイプ8、Flagsは必ず0010(QoS 1)
残りの長さ(Remaining Length) 1〜4バイト 例:0x0A(10バイト) Variable Header + Payloadの合計サイズ
Variable Header パケット識別子(Packet Identifier) 2バイト 例:0x00 0x0A SUBACKとの対応に使うID
Payload トピックフィルターの長さ 2バイト 例:0x00 0x05 トピック名の文字数
トピックフィルター + QoS N + 1バイト 例:`topic` + `0x01` 購読するトピック名と希望QoS
QoSレベルの意味
QoS 意味 説明
0 At most once 最低1回(届かない可能性あり)
1 At least once 最低1回(重複する可能性あり)
2 Exactly once 重複なしで1回だけ(最も信頼性が高い)

3.3.1 SUBACKパケット

SUBACKパケットは、クライアントが送ったSUBSCRIBEパケットに対して、MQTTブローカが「その購読リクエストを受け付けました」と応答するために返すパケットです。

SUBACKパケット全体フォーマット
セクション 項目名 サイズ 内容 備考
Fixed Header パケットタイプ & フラグ 1バイト 0x90 SUBACKはタイプ9、Flagsは0000(固定)
残りの長さ(Remaining Length) 1〜4バイト 例:0x03(3バイト) Variable Header + Payloadの合計サイズ
Variable Header パケット識別子(Packet Identifier) 2バイト 例:0x00 0x0A 対応するSUBSCRIBEのIDと一致
Payload Return Code(QoSレベル) 1バイト × トピック数 例:0x00, 0x01, 0x02, 0x80 各トピックに対する応答。0x80は購読拒否
(複数トピックの場合) 可変 例:0x00 0x01 0x80 SUBSCRIBEで指定した順に並ぶ
Return Codeの意味(QoS応答)
コード 意味 説明
0x00 QoS 0 At most once(最低1回)
0x01 QoS 1 At least once(最低1回、重複の可能性あり)
0x02 QoS 2 Exactly once(重複なしで1回)
0x80 失敗 そのトピックは購読できない

3.4 PUBLISHパケット

PUBLISHパケットは、クライアントまたはMQTTブローカが「このトピックにメッセージを送ります」と通知するために送るパケットです。

PUBLISHパケット全体フォーマット
セクション 項目名 サイズ 内容 備考
Fixed Header パケットタイプ & フラグ 1バイト 例:0x30(QoS 0) タイプ3(PUBLISH)+フラグ(DUP, QoS, RETAIN)
例:QoS 1なら 0x32、QoS 2なら 0x34
残りの長さ(Remaining Length) 1〜4バイト 例:0x0F(15バイト) Variable Header + Payloadの合計サイズ
Variable Header トピック名の長さ 2バイト 例:0x00 0x05 トピック名の文字数
トピック名 Nバイト 例:`topic` → 0x74 0x6F 0x70 0x69 0x63 メッセージの送信先
Variable Header(QoS 1以上) パケット識別子(Packet Identifier) 2バイト 例:0x00 0x0A QoS 1または2のときのみ含まれる
Payload メッセージ本体 可変 例:`Hello` → 0x48 0x65 0x6C 0x6C 0x6F 送信するデータ
PUBLISHパケットのフラグ構成(1バイト目)
ビット位置 名前 値の意味 備考
7〜4 Packet Type 0x3(= PUBLISH) 常に `0011`(4ビット)
3 DUPフラグ 1 = 再送、0 = 初回送信 QoS 1または2のときのみ意味を持つ
2〜1 QoSレベル 00 = QoS 0
01 = QoS 1
10 = QoS 2
メッセージの配信品質
0 RETAINフラグ 1 = MQTTブローカに保持させる
0 = 保持しない
新規購読者にも最後のメッセージを配信

3.4.1 PUBACKパケット

PUBACKパケットは、QoS 1で送信されたPUBLISHパケットに対して、MQTTブローカや受信側が「メッセージを受け取りました」と応答するために返すパケットです。

PUBACKパケット全体フォーマット
セクション 項目名 サイズ 内容 備考
Fixed Header パケットタイプ & フラグ 1バイト 0x40 PUBACKはタイプ4、Flagsは0000(固定)
残りの長さ(Remaining Length) 1バイト 0x02 Variable Headerのサイズ(2バイト)
Variable Header パケット識別子(Packet Identifier) 2バイト 例:0x00 0x0A 対応するPUBLISHのIDと一致
Payload なし 0バイト PUBACKにはPayloadは存在しない

3.5 MQTTパケットのシーケンス

MQTTの各パケットのHexペイロードをバイト単位で理解できたと思います。次に実際のパケットの流れを確認します。ここではQoSレベル0の例を以下に示します。QoSレベル0ではPUBACKパケットが発生しない ことに注目してください。
image.png

4. SocketDebuggerでの実践

ここからはいよいよ SocketDebuggerを使った手作業でのMQTT通信体験 です。前章で解説した各パケットのバイト構造を意識しながら、実際にパケットを作成して送信してみましょう。

4.1 前提条件

  1. わかりやすさを優先してシンプルなパケットのやり取りを確認します
    • 新規セッション
    • 認証・Willなし
    • QoS 0
  2. 今回は無料のインターネット上のMQTTブローカを使用するため、送信するデータは公開されてもよい内容のデータとします

4.2 SocketDebuggerの起動と接続設定

  1. SocketDebugger① を起動します
  2. ポート1の通信設定画面で無料のインターネット上のMQTTブローカを指定してTCP接続します
    • 通信タイプ:TCPクライアント
    • IPアドレス:5.196.78.28 (test.mosquitto.org)
    • remoteポート番号:1883
  3. SocketDebugger② を起動し、上記と同じ設定でMQTTブローカにTCP接続してサブスクライブ受信の準備をします

4.3 SocketDebugger①からMQTTブローカへCONNECTパケット送信

SocketDebugger①の送信データエディタに以下の CONNECTパケット を入力してください。
image.png

CONNECTパケット入力後、送信ボタンをクリック すると…
MQTTブローカにCONNECTパケットが送信され、すぐにMQTTブローカから CONNACKパケット が返ってきます!
image.png

4.4 SocketDebugger②からMQTTブローカへCONNECTパケット送信

SocketDebugger②の送信データエディタに以下の CONNECTパケット を入力してください。
image.png

同様にCONNECTパケット入力後、送信ボタンをクリック すると…
こちらも問題なくMQTTブローカにCONNECTパケットが送信され、すぐにMQTTブローカから CONNACKパケット が返ってきます!
image.png

注意
SocketDebugger①、②のそれぞれのクライアントIDはユニークにしてください。(同じクライアントIDで接続すると、MQTTブローカ上で片方の接続が切断されます)

  • SocketDebugger①:client1
  • SocketDebugger②:client2

4.5 SocketDebugger②からMQTTブローカへSUBSCRIBEパケット送信

SocketDebugger②の送信データエディタに以下の SUBSCRIBEパケット を入力してください。
検証用として、トピックを「udom/topic」とします。
image.png

SUBSCRIBEパケット入力後、送信ボタンをクリック すると…
MQTTブローカにSUBSCRIBEパケットが送信され、すぐMQTTブローカから SUBACKパケット が返ってきます!
SUBSCRIBEパケットで指定したパケット識別子になっていることに注目してください。
image.png

4.6 SocketDebugger①からMQTTブローカ(→SocketDebugger②)へPUBLISHパケット送信

SocketDebugger①の送信データエディタに以下の PUBLISHパケット を入力してください。
トピックはSUBSCRIBEパケットで指定した「udom/topic」にします。
「udom/topic」宛に送りたいメッセージを「Hello」とします。
image.png

PUBLISHパケット入力後、送信ボタンをクリック すると…
SocketDebugger①からMQTTブローカにPUBLISHパケットが送信され、MQTTブローカはそのままPUBLISHパケットをSocketDebugger②へ送信します。 その証拠として SocketDebugger②PUBLISHパケット が届いています!
image.png

また、SocketDebugger①にはPUBLISHパケット送信後にMQTTブローカから PUBACKパケットが届いていない ことが確認できます。これも期待通りです!
image.png

5. まとめ

今回は、前回の記事で紹介した MQTTのシンプルな仕組みを理解する概念編 に続き、実際に SocketDebuggerを使って手作業でMQTT通信を行う実践編 を紹介しました。ポイントは以下の通りです。

  • MQTTはTCP接続後に、最初に CONNECTパケット を送信することでセッションが確立される
  • クライアントIDはMQTTブローカ上で一意である必要があり、同じクライアントIDで新しい接続が確立されると、既存の接続は切断される
  • CONNECTの次には、 SUBSCRIBE(購読)や PUBLISH(送信)といった制御パケットを送ることで、実際のメッセージ交換が行える
  • SocketDebuggerのようなツールを使うと、TCPレベルのペイロードを直接確認でき、MQTTの仕組みを学習するのに有効

今後は、この記事で得た知識をベースに、SocketDebuggerを使った スクリプトによる自動化 や、QoSやWillメッセージなどの応用的な仕組み にも挑戦していけると、さらに理解が深まるでしょう。

新人研修や自習の一環として、ぜひ今回の内容を実際に試してみてください!👍

禁止事項

本記事では学習用に 無料のMQTTブローカ(test.mosquitto.org) を使用しました。無料MQTTブローカは誰でもアクセスできるため、

  • 機密事項や個人情報
  • 業務上の重要なデータ

絶対に送信しないでください
実運用では、必ず認証・暗号化を備えた専用のMQTTブローカを利用してください。

6. 付録:無料MQTTブローカ一覧

以下は、雑誌「Interface」2025年10月号(CQ出版社)掲載の表を引用したものです。
MQTTサービス名 URL(サービス説明ページ) サービスの特徴 経路暗号化
Mosquitto Test Server https://test.mosquitto.org/ 接続検証が主目的のサービス 選択可
EMQX Public MQTT Broker https://www.emqx.com/ja/mqtt/public-mqtt5-broker ユーザ登録なしに利用可能な一般公開サービス 選択可
EMQX Serverless MQTT Service https://www.emqx.com/ja/cloud/serverless-mqtt ユーザ登録することで、無料の専用サービスとして利用可能 必須
HiveMQ Free Public MQTT Broker https://www.hivemq.com/mqtt/public-mqtt-broker/ ユーザ登録なしに利用可能な一般公開サービス 選択可
HiveMQ Cloud Serverless https://www.hivemq.com/products/mqtt-cloud-broker/ ユーザ登録することで、無料の専用サービスとして利用可能 必須
shiftr.io Public MQTT Broker https://www.shiftr.io/try ユーザ登録なしに利用可能な一般公開サービス 選択可
shiftr.io MQTT Cloud Service https://www.shiftr.io/cloud/ ユーザ登録することで、無料の専用サービスとして利用可能。ダッシュボードにより接続状況が表示される。 選択可

MQTT公式仕様

MQTTについて、もっと深く知りたい方は公式の以下のサイトをご参照ください。
本記事のMQTTパケット構造の解説はこちらを参考にして記載しています。

記事リンク

株式会社ユードム

株式会社ユードムはITと人間力で社会に貢献します。

SocketDebuggerのご購入はこちら(期間限定の試用版もあります)
https://www.udom.co.jp/sdg/index.html

9
9
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?