メッセージ構造定義
独自プロトコルの TCP/UDP 通信では、固定ヘッダ+可変ボディや、コマンドごとに異なるバイナリ構造を扱うことがよくあります。メッセージ構造定義を使うと、受信データの構造をフィールド単位で定義しておき、
- 受信ログをフィールド単位に分解して表示する(どのバイトが何の値か一目でわかる)
- フィールドの値で応答を出し分ける(→ バイナリ構造応答)
ことができます。構造体定義・バイト順序(エンディアン)・メッセージ分割方式(フレーミング)はプロジェクト全体で共有され、プロジェクトファイルに保存されます。
この機能は主にバイナリプロトコル(HEX)向けです。テキスト行ベースの通信はオートメーションで十分なことが多いです。
全体の流れ
- メニューバーの 「プロジェクト」→「プロジェクト設定…」 を開き、プロジェクトのエンディアンとフレーミング方式(TCP ストリームの区切り方)を設定する。
- メニューバーの 「プロジェクト」→「構造体定義…」 を開き、メッセージの構造体定義を 1 つ以上作る(フィールドを並べる)。
- セッションを起動して受信すると、ログペインでパース結果が確認できる(「構造体パース表示」をオン)。
- フィールドの値に応じて応答を返したい場合は、「バイナリ構造応答」タブで構造体ルールを追加する(→ バイナリ構造応答)。
プロジェクト設定(データ形式・エンディアン・フレーミング)
メニューバーの 「プロジェクト」→「プロジェクト設定…」 で開くダイアログで設定します。ここはプロジェクト全体(全セッション共通)の設定です。
各画面項目の詳細説明は プロジェクト設定 を参照してください。
既定データ形式(テキスト/バイナリ)
このプロジェクトで新規に作る項目(送信ステップ等)の既定の解釈方式です。UTF-8 / ASCII = テキスト、RawHex = バイナリ(HEX) を選びます。各セッション側で個別に上書きできます。
エンディアン
数値フィールド(u16/i32/f32 など)を解釈するバイト順序です。接続する機器の仕様に合わせてリトルエンディアン / ビッグエンディアンのどちらかを選びます。
フレーミング方式(TCP ストリームの区切り)
TCP は連続したバイトストリームのため、「どこからどこまでが 1 メッセージか」を決める必要があります。次のいずれかを選びます。
| 方式 | 説明 |
|---|---|
| None | 区切らない。受信したチャンクをそのまま 1 メッセージとして扱う(UDP やデータグラム的な使い方向け) |
| LengthPrefixed | ヘッダ内の長さフィールドでメッセージ長を判定する(最も一般的) |
| FixedLength | 毎メッセージ固定長 |
| Delimiter | 区切りバイト列で分割 |
フレーミング方式を選ぶと、その方式で意味を持たない設定項目は自動的にグレーアウト(編集不可)になります。有効になっている欄だけを入力すれば設定できます。
| 方式 | 有効になる詳細項目 |
|---|---|
| None | なし(詳細項目はすべてグレーアウト) |
| LengthPrefixed | 共通ヘッダ長 / 長さフィールドのオフセット・サイズ / 長さ基準 / 長さ補正 |
| FixedLength | 固定メッセージ長 |
| Delimiter | デリミタ HEX(例 0D 0A) |
各詳細項目の意味:
| 項目 | 説明 |
|---|---|
| 共通ヘッダ長 | 全メッセージに共通する固定長ヘッダのバイト数 |
| 長さフィールド: オフセット | ヘッダ先頭から長さフィールドまでのバイト位置 |
| 長さフィールド: サイズ | 長さフィールド自体のバイト数(1 / 2 / 4 など) |
| 長さ基準 | 長さフィールドの値が指す範囲(メッセージ全体長 / 長さフィールド以降 / ボディのみ) |
| 長さ補正 | 長さ基準に対する補正値(±整数)。長さフィールドの値と実測長が合わないときに調整 |
| 固定メッセージ長 | 1 メッセージとして切り出すバイト数 |
| デリミタ HEX | 区切りバイト列を HEX で指定(例 0D 0A) |
前提: LengthPrefixed は、全メッセージに共通する固定長ヘッダが先頭にあることを前提にしています(ヘッダ内の整数フィールドからメッセージ長や種別を読み取るため)。
構造体定義の作成
メニューバーの 「プロジェクト」→「構造体定義…」 で開くダイアログで管理します。
- 追加 / 編集 / 複製 / 削除: 定義の作成・編集(行をダブルクリックでも編集)・複製・削除。
- インポート / エクスポート: 定義を
.commsim-structファイルとして書き出し/読み込み。別プロジェクトへ定義を再利用できます。
「追加」「編集」で開く 「構造体定義の編集」 ウィンドウで、フィールドを先頭から順に並べます。
フィールド表
| 列 | 説明 |
|---|---|
| 名前 | フィールド名(「長さ元 / 個数元」や応答テンプレートから参照される) |
| 型 | u8〜u64 / i8〜i64(符号付き)/ f32・f64(浮動小数点)/ ascii(文字列)/ hex(生バイト)/ bcd(パック BCD)/ array(配列)/ nested(入れ子) |
| 役割 | None / Length(長さフィールド)/ Checksum(チェックサム)/ Discriminator(判別) |
| 固定長 | ascii / hex / bcd の固定バイト数(可変長なら空にして「長さ元」を使う) |
| 長さ元 | 可変長フィールドの長さを、先に出てくる整数フィールドの値から取る場合にそのフィールド名を指定 |
| 個数元 | array の要素数を、整数フィールドの値から取る場合にそのフィールド名を指定 |
行は 行追加 / 行削除 / ↑ / ↓ で編集・並べ替えします。
長さ元 / 個数元の参照名は、入れ子内でもフラットなフィールド名(プレフィックスなし)で指定します。
判別フィールド(複数定義の出し分け)
コマンドごとに構造が違う場合、定義を複数作り、判別フィールドで適用する定義を選びます。
- 「判別フィールドで適用を分岐する」をオンにし、判別フィールド名と一致値(
0x10または16の形式)を指定します。 - 受信時、ヘッダの判別フィールド値が一致する定義が適用されます。
- 複数の定義が一致した場合は先頭(定義一覧の上から最初)を採用します。
- どの定義にも一致しない場合は、判別なしの定義(あれば最後の受け皿)→ それも無ければ生 HEX 表示にフォールバックします。
プレビュー
編集ウィンドウ下部の「プレビュー」にサンプル HEX(例 00 10 00 05 48 65 6C 6C 6F)を入力して「パース」を押すと、その定義でどう分解されるかを確認できます。設計しながら検証できます。
プレビュー入力欄は専用のバイト入力(HEX エディタ)です。ログ・キャプチャの HEX ダンプをそのまま貼り付けて検証できます。
受信ログでのパース表示
セッションを起動して受信すると、ログペインの「構造体パース表示」チェックボックス(既定オン)がオンのとき、フレーミングで切り出した各メッセージがフィールドごとに分解されてログに表示されます。
- 数値フィールドは
値 (0x..)形式で表示されます。 - 一致する定義がない場合は生 HEX で表示されます(警告付き)。
チェックをオフにすると従来どおりの生データ表示に戻ります。
設定例
フレーミング設定例
LengthPrefixed:先頭 2 バイトが「以降のデータ長」を示す形式
ヘッダ 4 バイト(コマンド 1B + 予約 1B + 長さ 2B)+ ボディという構成で、長さフィールドがボディのバイト数を格納している場合の例です。
| 項目 | 設定値 |
|---|---|
| フレーミング方式 | LengthPrefixed |
| 共通ヘッダ長 | 4 |
| 長さフィールド: オフセット | 2 |
| 長さフィールド: サイズ | 2 |
| 長さ基準 | 共通ヘッダ以降のボディ長 |
| 長さ補正 | 0 |
| エンディアン | Big |
受信バイト例: 01 00 00 05 48 65 6C 6C 6F(ヘッダ 4B + ボディ 48 65 6C 6C 6F 5B)
FixedLength:16 バイト固定のメッセージ形式
コマンドと応答が常に 16 バイトで送受信されるプロトコルの場合です。
| 項目 | 設定値 |
|---|---|
| フレーミング方式 | FixedLength |
| 固定メッセージ長 | 16 |
Delimiter:行末 \r\n(0D 0A)で区切るテキスト寄りのバイナリ形式
テキスト行に近いが構造体パースも使いたい場合(改行区切りのセンサーログなど)の例です。
| 項目 | 設定値 |
|---|---|
| フレーミング方式 | Delimiter |
| デリミタ HEX | 0D 0A |
構造体定義例:コマンド + 長さ + 可変ボディ(コマンドで出し分け)
01 00 00 05 48 65 6C 6C 6F のようなメッセージを想定した定義例です。
| フィールド名 | 型 | 役割 | 固定長 | 長さ元 |
|---|---|---|---|---|
| Command | u8 | Discriminator | — | — |
| Reserved | u8 | None | — | — |
| BodyLen | u16 | Length | — | — |
| Body | hex | None | — | BodyLen |
Commandを Discriminator(役割: Discriminator)にすることで、コマンド値ごとに別の構造体定義を選択できます。BodyはBodyLenの値をバイト数として参照する可変長フィールドです。
コマンドで定義を出し分ける場合(例: Command = 0x01 と Command = 0x02 で異なる定義を使う):
- 定義 A: 「判別フィールドで適用を分岐する」をオン → 判別フィールド名:
Command、一致値:0x01 - 定義 B: 同様に一致値
0x02 - どちらにも一致しない場合は判別なしの定義(受け皿)または生 HEX 表示にフォールバックします。
プレビュー欄にサンプル HEX(例
01 00 00 05 48 65 6C 6C 6F)を貼り付けて「パース」を押すと、定義通りに分解されるかその場で確認できます。
次に読む
- 白紙から作るハンズオン → メッセージ構造定義を白紙から作る
- フィールド条件に基づく応答 → バイナリ構造応答
- テキスト/HEX の条件応答・定期送信 → オートメーション