プロトコルってなんだ?(その1)

プロトコルとは?

通信におけるプロトコルというのは、通信の規約…つまりルールとか取り決めとか約束事とかのことです。今回はこの通信プロトコルについてのお話。ソースコード書いたり、小難しい話はせずにマイルドな記事にするつもりです。

プロトコルがなぜ必要なのか

まずは、コンピュータを使わないアナログな通信を考えます。例えば、機械類が全く無いような時代で、声が届かない程度の距離にいる人にすばやく何か情報を伝える必要がある場合、どんな方法が考えられるでしょうか?

  • 鐘を鳴らす
  • ほら貝を吹く
  • 指笛を吹く
  • 旗を振る
  • のろしをあげる

では、あなたが何百年前の時代にタイムスリップしたとして、遠くから「カンカンカン!」とけたたましく鐘を鳴らす音が聞こえてきたとしましょう。「何か危険を知らせるものだろうか?」ということは雰囲気から察したりすることができるかもしれませんが、「どんな危険が迫っている?」「私はどうすべき?」という情報はわからないでしょう。

鐘以外でも同様で、ほら貝や指笛の音が聞こえたり、旗やのろしが上がっているのが見えたとしても、その意味するところがさっぱりわかりません。

当然、鐘を鳴らしている人は意味も無くテキトーに鳴らしているのではなく、何か伝えたい情報があって鐘を鳴らすわけです。そして、その鐘の音を聞くべき当事者たちの間では鐘の鳴らし方に何らかのルールを決めていて、その鐘を聞けば何を伝えたいのかを判断できるはずです。

こういった「通信手段として何を使うのか」「こういう鳴らし方(や動き)の時はこういう意味だ」というような取り決めを通信したい当事者同士が共有した時に、はじめて通信は成立します。このルール・取り決めこそが「プロトコル」なのです。

サンプル: 鐘プロトコル 1.0

  • これは何らかの異常事態を警報するためのプロトコルである。
  • 通信媒体として鐘(の音)を使う。
  • 最低でも 100m の距離まで音が聞こえる程度の音量が出せる鐘を使用すること。
  • 鐘を鳴らすリズムは一定に保つこと。
  • 以下のようなパターンで鐘を鳴らすことで、警報の意味を示す。
意味 鳴らし方(繰り返す)
敵襲あり OOOO
火災発生 OOO-
川の氾濫 O-OO--
その他 O--

O で鐘を鳴らし、- で1拍休み。

もっと多くの情報を伝えたい

鐘によって「敵襲あり」ということがわかったとしても、「どこの軍がどこから来たのか?」「兵力がどれぐらいなのか?」「何をすればいいのか?」といった情報はわかりません。プロトコルを修正して、鐘の鳴らし方にそういった情報を加えることもできるかもしれませんが、乗せたい情報が増えれば増えるほど鐘の鳴らし方は複雑化することでしょう。

こうなると、伝えたい単語が増えるたびにルールをどんどん増やしていくのではなく、文字や数字に対応した鐘の鳴らし方をルール化しておいて、文字の並びで文章を伝える方が便利そうです。

モールス信号のようなものですね。文字と鐘の鳴らし方を対応づけることで、任意の文字列を送信できます。学習コストはかかりますが、任意の文字列を伝えられるので情報量は圧倒的に増えるはずです。他の通信手段の場合でも、文章を伝えられるようにすることで情報量を増やすことができそうです。

サンプル: 鐘プロトコル 2.0

  • これは何らかの異常事態を警報するためのプロトコルである。
  • 通信媒体として鐘(の音)を使う。
  • 最低でも 100m の距離まで音が聞こえる程度の音量が出せる鐘を使用すること。
  • 鐘を鳴らすリズムは一定に保つこと。
  • まず、表Aのパターンで10秒程度継続して鐘を鳴らし、警報の大分類を示す。
  • 4拍以上の休みを置く
  • 表Bのパターンで鐘を鳴らして文章をつくり、詳細情報を示す。
  • 4拍以上の休みを置き、もう一度同じ文章を送信する。
  • 4拍以上の休みをおき、「以上」を示す鐘を1回鳴らす。

表A

意味 鳴らし方(繰り返す)
敵襲あり OOOO
火災発生 OOO-
川の氾濫 O-OO--
その他 O--

表B

文字 鳴らし方
O-O-OO-O-
OO-
OOO-
(以下略)

O で鐘を鳴らし、- で1拍休み。

デジタルなプロトコルへ

時代は進み、コンピュータが使える時代になると、通信の媒体は電気や電磁波(電波、赤外線、光など)を使ったものが主流となりました。また、人同士で通信することよりも機器同士での通信が多くなり、文章を伝えるというよりは、より汎用的に「データ」を伝えることを考えてプロトコルが設計されます。

コンピュータの世界ではデータは 0 と 1 の2値で表現されるビット列です。よって、「どのようにビット列を送受信するのか」「そのビット列をどのように意味ある情報として解釈するのか」などといったことがプロトコルとして定められます。

さらに、複数の機器同士が接続されたネットワーク上で通信を行う場合には、追加で定めなければならないルールがたくさんあります。

  • 物理的な通信媒体は何か?
  • 通信媒体を使ってどのようにビット列を送受信するか?
  • 信号のノイズや欠損にはどのように対処する?
  • 複数の機器間で通信を行うには?
    • 機器同士を繋ぐネットワークの構築方法は?
    • 宛て先の指定方法は?
    • どのように宛て先にデータを届けるのか?
    • 通信経路上で障害が生じた場合の対処方法は?
    • 複数の通信が渋滞したり衝突しないように制御する方法は?
    • 盗聴や改ざん、なりすましなどの対策は?
  • 送受信されたデータの解釈方法は?
  • etc…

ルールをできるだけ複雑化させないため、現代の通信においてはたくさんのプロトコルを組み合わせることで通信を実現していることがほとんどです。プロトコル間の依存関係を疎結合にしておくことで、特定のプロトコルだけを都合の良いものに挿げ替えたりすることが簡単になります。

例えば、無線LANを使って対戦ゲームで遊んでいたけど、ちょっと電波状況が悪いからLANケーブルに変えよう…ということが気軽にできます。これはゲーム機とルーター間の通信プロトコルが変化していますが、ゲームアプリケーション同士の通信には特に影響はなく、結果的に通信相手に届くビット列も変化しません。

もう少し踏み込んで調べたい人は、「OSI参照モデル」について調べてみてください。

アプリケーション同士の通信プロトコル

通信機能をもったアプリケーションを作りたい場合、アプリケーション間で通信するため、やはりプロトコルが必要になります。送信するデータには何を含めるのか、受信したデータをどういう風に解釈するのか、データのやり取りの流れはどうなるのかといったルール決めです。

ゲーム開発でも、通信機能があるのであればこういったアプリケーションプロトコルを考える必要があります。

データをどういう通信経路で宛て先に届けるのかとか、信号のノイズ対策がどうだとか、ケーブルの配線がどうだとか、無線LANが使われていたらどうだとかいった部分はアプリケーションプロトコルはまったく気にしなくて構いません。それらは他のプロトコルで決めることです。

例えば、ネットワーク対戦機能を持った○×ゲームを実装したいとしましょう。

既に対戦相手との接続が確立されており、いまゲームがスタートして○側の最初の手番です。×側は○側が盤面のどこかに○を置くまで待機しています。

○側プレイヤーが盤面の真ん中に○を置きました。待機している×側にこのことを伝えなければなりません。盤面のマス目の位置を示す方法がないと「どこに置いた」という情報を伝えられないため、以下のようにマス目に番号を割り振ることにしましょう。

○側は 4 の位置に○を置いたので、4 という数値だけを相手に送信すれば良さそうです。送信し得る値は 0~8 の 9 種類しか無いので、4bit あれば事足りますが、ほとんどの通信プロトコルのデータの最小単位は1オクテット(=8bit)なので、8bit の整数として送信することにしましょう。送信したら、○側は×側が何か盤面に置くまで待機します。

×側は受け取ったデータを 8bit の整数として読み取り、それをマス目の位置を示す番号と解釈します。相手は○側なので、盤面の 4 のマス目(真ん中のマス目)に○を置きます。プレイヤーに×を置く位置を選択するように促し、プレイヤーが×を盤面に置いたら、先ほどと同様に置いたマス目の番号を○側に送信し…と繰り返します。

盤面がいっぱいになるか、タテヨコナナメのどこか1列に同じ印が揃ったらゲームが終了し、通信を切断します。

こういった取り決めがこの○×ゲームのアプリケーションプロトコルになります。実際にはゲーム開始前の対戦相手との接続に関するプロトコルとか、通信エラー処理をどうするかとか、不正対策をどうするかとか、そのあたりのことも考える必要があります。

また、リアルタイム性の強いアクションゲームだと、少しでもラグを感じにくくするために様々な工夫をこらす必要があったりと、プロトコル設計もなかなか奥が深いものです。

次回、家電を操作するプロトコル編

長くなってきたので今回はここまで。次回はPCやゲームとは違う身近な家電のプロトコルについて触れていきたいと思います。

お知らせ

株式会社グレッゾではエンジニアを募集しております!
もしご興味がありましたら是非、下記リンクより応募よろしくお願いします。
https://www.grezzo.co.jp/jp/careers/