独自プロトコルを作りたい Part.1 【西田の戯言。】

前回の記事で現在の部室内のネットワークについての問題をお伝えしました。実はここで私は考えていることがあります。いっそ一括で管理するためのサービスを提供できないかと。

OECU Advent Calendar 2025

この記事は、OECUアドベントカレンダー 2025 23日目の記事です。

実現したいプロトコル

さて、今回実現したいプロトコルを簡単に説明したいと思います。そもそも、どんなシステムを実現するためにプロトコルを作りたいのか説明します。

今回作りたいシステムは、簡単に言えばネットワーク内のホスト検索システムです。今回のプロトコルでは、ホストの情報を得るために使用したいと考えています。

ホストの情報には、CPUやOS、NICの情報を考えています。そして、プロトコルの性質上、アプリケーション層のプロトコルで完結できそうです。

プロトコルとして決めなければいけないこと

さて、プロトコルを設計するにあたって、事前に決めておかなければならない事項がいくつかあります。あらかじめ整理しておきましょう。

  • 通信方式
  • データ表現方式
  • プロトコル機能
  • バージョン方式

通信方式は、下位層の通信方式。特にトランスポート層の形式は決めておきたいです。

そしてデータ表現方式。これは、どのような表現でデータを記載するかという点を決めます。後述しますが、今回はテキストベースなので、どのような形式でデータを詰め込んでいくかに付いて決めなければなりません。

次にプロトコル機能。今回は、システムとプロトコルがほぼ同じタイミングで開発されることになるため、どこまでの仕様・機能をプロトコルに含んで、どこからをシステムの仕様・機能にするのかを決める必要があります。汎用的なプロトコルに拡張したいことを考えると、システムに依存する形ではなく、ある程度プロトコル側に仕様を詰めておくと、おいおいサードパーティ製みたいな第三者のソフトにも展開しやすくなります。

拡張性という視点では、この時点でバージョンについても考えておくといいかもしれません。特に、まだシステムの仕様も固まってない状態でプロトコルの仕様を考えているので、今後、変更や拡張が考えられます。なので、今のうちにバージョンの付番方式・管理方針についても決めておきます。

これらの項目について順に検討し、本プロトコルの設計を具体化していきます。

プロトコルの基本的な仕様

アプリケーション層のプロトコルと言いました。ここで決めないといけないことがいくつかあります。

通信方式

まず、トランスポート層の方式です。今回は言わずもがなTCPを使用します。が、システム的に一部UDPを使用することを考えています(後述します)。

TCPを採用する理由について一応言語化しておきます。

  • ホストの情報を正確に取得するという性質上、信頼性が保証されているTCPのほうが良い
  • リアルタイム性はそこまで重要ではない

今回は、アプリケーション層のプロトコルということで、再送制御などはTCPに任せて、アプリケーションの実装に集中できます。

TCPコネクションのライフサイクルについては、検討段階ではありますが、1コネクション1メッセージにしようと思います。もうしかしたら、無駄なコネクションが出てしまうかもしれませんが、一度試してみて再検討することにします。

そして、データのやり取りに関しては、リクエスト・レスポンス型を採用することにします。この部分はもう少し仕様を詰める必要があると思いますが、現時点ではこれ以上の決定は避けたいと思います。

さて、一部UDPを使用するという点ですが、これはホスト探索に使用しようと思います。これをプロトコル仕様に乗せるか、システムとしての機能として分けるかについては議論の余地がありますが・・・。

データ表現

次にデータ表現の方式。これはテキストベースのデータ表現を採用することにしました。

理由としては、運用の都合上特段難読化する必要がない点、構造化されたキー・バリュー形式を前提とするJSONやYAML等への拡張移植が簡単な点などが挙げられます。

文字コード・改行コードはUNIX系システムで使うことを考えて、UTF-8とLFで参りましょう。

プロトコルの機能

さて、プロトコルの機能です。

アプリケーション層のプロトコルということで、基本的にデータ表現に集中することができそうです。

  • ホストの基本情報を収集・送信する
  • サーバ側でホスト情報を受理・記録する
  • 正常・異常の応答を返す

これがプロトコル仕様で定めておく必要がある最低限の仕様でしょうか。

逆に、今回のプロトコルでは、暗号化・認証・認可・監視等の機能は無視します。後述しますが、より下位層での暗号化で対応できないかなぁとか考えています。

バージョン

プロトコルはある程度の互換性をもたせようと思いますが、多分システムの開発中にプロトコルの仕様も変える気がするし、運用してから機能を追加したくなると思うのでバージョンで管理するようにしたいと思います。

メジャーバージョンとマイナーバージョンにしておいて、マイナーバージョン間では互換性を提供するが、メジャーバージョン間は互換性を保証しない、というような運用がわかりやすいかな?

メッセージフォーマット

メッセージフォーマットについて説明します。メッセージフォーマットとは、どのようなデータを、どのような構造でメッセージとして表現するかを定義するものです。

ヘッダーとボディ

本題に入る前に、メッセージにおける「ヘッダー部」と「ボディ部」について軽く説明しておこうと思います。

メッセージは大きく、ヘッダー部とボディ部に分けることができます。

ヘッダー部は、メッセージ解釈のメタデータが含まれています。これは、メッセージをどのように扱うかを記述するための部分です。この部分は基本的に固定長です。

なお、ここでいうヘッダー部は、TCPストリーム上でのフレーム構造とは区別した、メッセージ内部の論理構造を指します。

一方、ボディ部がメッセージの本体が入ります。この部分は基本的に可変長です。

それぞれの役割と特性をマトリックスに起こしてみます。

観点 ヘッダー部 ボディ部
主な役割 メッセージの扱い方を示す メッセージの内容を表現する
情報の性質 メタデータ 実データ
可変性 低い 高い
サイズ 小さい 大きくなりやすい
パース順序 最初に解析される ヘッダー解釈後に解析
拡張頻度 低い 高い
互換性への影響 大きい 比較的小さい
主な利用者 プロトコル実装 アプリケーション層

まとめると、固定的で制御的な情報を書き込むのがヘッダー、可変的で実際の情報を書き込むのがボディということです。

考えられるメッセージフォーマット

現時点でメッセージフォーマットを2択で検討しています。

  • ヘッダー部にすべてのデータを書き込む
  • ボディ部にJSON形式でデータを記述する

前者は、ヘッダー部に実データまで含めて記述するという設計です。ヘッダー部は、構造が単純でキーバリュー方式で情報を格納するのが楽です。一方で、ヘッダー部のデータはプロトコルの仕様にダイレクトに影響を与えるため、プロトコルの互換性を維持するのは難しくなります。

後者は、ボディ部にデータを突っ込む設計です。こちらはJSONで記述する方針で柔軟に対応できます。こちらは、柔軟に対応できる分、構造的に単純ではなくなります。更にJSONパースも必要となります。

これまた、マトリックスで双方の特長を抑えたいとおもいます。

観点 ヘッダー方式 ボディ方式
基本思想 キーバリュー的な使い方 データを構造化
可変長データ 不向き 得意
拡張性 低い 高い
後方互換性 維持が難しい 維持しやすい
実装の単純さ 初期は単純 JSONパースが必要
設計変更の影響 大きい 小さい

今回は、以下の理由からボディ方式を採用します。

  • 搭載されるすべてのNICの情報が欲しい(NICの数は不定)ため、可変長に対応できるようにしたい
  • プロトコルの仕様を大雑把にですが先に決めているので、仕様変更に耐えるプロトコルにしたい
  • 今後の拡張が考えられるため、互換性の維持も楽な方が良い
  • ボディ方式はJSONパースが必要だが、どんな言語・フレームワークでもJSONパースは便利なライブラリがあり、それほどコストの増大に繋がらない

まとめ

ということで、独自プロトコルを作りたい企画 Part.1でした。

今回は「やってみたいこと」ができたタイミングと、アドベントカレンダーの時期がちょうどいい感じに被ったので、記事にしてみました。実際に記事をブログ形式ですが文章にまとめることで考えが整理できた気がします。

あと、こうしておけば、続きを待ってくれる人がいるかも知れないという形でいい感じに圧になるので、逃げ道がなくなりますね。やったね!

この先は、ボディ部に書き込むJSONの具体的なスキーマを定義しつつ、それを送受信するサンプルプログラムを実装していく予定です。

アドベントカレンダーとは関係なく進みますが、お楽しみに!

あとがき

先日、大阪電気通信大学 四條畷キャンパスの学祭「なわフェス」に行ってきました。

吹奏楽団と縁がありまして、後輩たちの演奏を聴いてきました。加えて、楽器の運搬のお手伝いも少しだけさせていただきました。

この演奏をもって4年生が引退ということで、淋しくもあり。

出会いもあれば別れもあるんだなぁと。とかいいながら、OBになってはや9ヶ月。ずっと通信研究会やらOPCやら吹奏楽団やらと関わり続けているわけですが。

今年ももう終わり、アドベントカレンダーも残すところ2日。つまりクリスマスまで残り2日ということです。メリークリスマス!

サンタさん、私にSwitch 2をください。


この記事を書いた人

西田(総合情報学部 情報学科 2021年入学)

通信研究会OB。当ホームページの保守運用を支援しています。組み込み系のソフトウェアエンジニア。応用情報技術者・修習技術者。