ネットワークバイトオーダー(ネットワークバイトオーダー)とは | 意味や読み方など丁寧でわかりやすい用語解説
ネットワークバイトオーダー(ネットワークバイトオーダー)の意味や読み方など、初心者にもわかりやすいように丁寧に解説しています。
読み方
日本語表記
ネットワークバイトオーダー (ネットワークバイトオーダー)
英語表記
network byte order (ネットワークバイトオーダー)
用語解説
ネットワークバイトオーダーとは、コンピュータネットワーク上でデータを送受信する際に、複数バイトで構成される数値データの並び順(バイト順)を統一するための規約である。異なる種類のコンピュータは、数値データをメモリに格納する際のバイト順が異なる場合があり、そのままデータを交換すると、受信側で数値が正しく解釈されない問題が発生する。この問題を解決するため、TCP/IPプロトコルスタックでは、ネットワーク通信においては特定のバイト順を用いることを標準として定めており、これをネットワークバイトオーダーと呼ぶ。具体的には、最も重要なバイト(最上位バイト)を最初に、最も重要でないバイト(最下位バイト)を最後に配置する「ビッグエンディアン」という形式が採用されている。これにより、異なるシステム間で数値データを確実にやり取りできるようになる。
コンピュータのメモリ上では、整数などの複数バイトで構成される数値データは、連続したアドレス空間に格納される。この際、数値の各バイトをどのような順番で格納するかは、CPUの設計によって異なる。このバイトの並び順を「バイトオーダー」あるいは「エンディアン」と呼ぶ。
バイトオーダーには主に二つの種類がある。一つは「ビッグエンディアン」で、これは数値の最上位バイト(最も桁の大きい部分)をメモリの最も低いアドレスに配置し、最下位バイト(最も桁の小さい部分)を最も高いアドレスに配置する方式である。例えば、16進数の0x12345678という32ビット整数があった場合、メモリ上ではアドレスの低い方から順に12、34、56、78と並ぶ。もう一つは「リトルエンディアン」で、これは最下位バイトをメモリの最も低いアドレスに配置し、最上位バイトを最も高いアドレスに配置する方式である。同じ0x12345678の場合、メモリ上ではアドレスの低い方から順に78、56、34、12と並ぶことになる。
多くの組込みシステムや一部のRISC系プロセッサ(例: PowerPCの一部)はビッグエンディアンを採用している。一方、IntelやAMDのx86アーキテクチャのようなPCで広く使われているプロセッサはリトルエンディアンを採用している。このように、異なるアーキテクチャを持つコンピュータが混在する環境では、数値データのバイトオーダーが異なるため、そのままデータを送受信すると、受信側がデータを誤って解釈してしまう。例えば、リトルエンディアンのマシンが送信した0x12345678をビッグエンディアンのマシンが受信すると、それを0x78563412として解釈してしまう可能性がある。
この互換性の問題を解決するため、ネットワーク通信においては、データのバイト順を特定の形式に統一する必要がある。TCP/IPプロトコルスイートでは、この標準として「ビッグエンディアン」形式を採用した。この標準化されたバイト順が「ネットワークバイトオーダー」である。したがって、データをネットワークに送出する際には、たとえ送信側のコンピュータがリトルエンディアンであっても、送るべき複数バイトの数値データは必ずネットワークバイトオーダー(ビッグエンディアン)に変換しなければならない。逆に、ネットワークからデータを受信した際には、それがネットワークバイトオーダーであると仮定し、受信側のコンピュータのネイティブなバイトオーダーに変換し直す必要がある。
この変換作業を簡単に行うために、C言語の標準ライブラリ(特にBSDソケットAPI)には、バイトオーダー変換用の関数が提供されている。例えば、ホストバイトオーダーからネットワークバイトオーダーへの変換には、16ビット整数用としてhtons (host to network short)、32ビット整数用としてhtonl (host to network long) がある。ネットワークバイトオーダーからホストバイトオーダーへの変換には、それぞれntohs (network to host short) と ntohl (network to host long) がある。これらの関数は、送信元のホストが既にビッグエンディアンである場合には何もしない(変換不要なため)、リトルエンディアンである場合にはバイト順を入れ替える、という処理を内部で自動的に判断して実行する。プログラマはこれらの関数を使うことで、自身の環境のバイトオーダーを意識することなく、確実にネットワーク通信を行うことができる。
ただし、すべてのデータが変換の対象となるわけではない。ネットワークバイトオーダーの変換が必要なのは、2バイト以上の長さを持ち、数値として解釈されるデータのみである。例えば、IPアドレスやポート番号、プロトコルヘッダ内の長さフィールドなど、プロトコルで定義された複数バイトの数値フィールドがこれに該当する。一方、1バイト文字や純粋なバイト列(バイナリデータ)、既に文字列として表現されている数値データなど、個々のバイト自体に意味があり、その並び順が数値としての意味を持たないデータについては、バイトオーダーの変換は不要である。これらのデータは、メモリ上でのバイト順がそのままネットワーク上で伝送される。
ネットワークアプリケーションを開発する際には、プロトコル仕様に沿って、どのデータフィールドがネットワークバイトオーダーを必要とするかを正確に理解し、適切なタイミングで変換関数を適用することが不可欠である。データ構造を定義する際には、バイトオーダーの問題を考慮し、異なるシステム間での互換性を保つ設計が求められる。また、構造体内のフィールドのパディング(メモリ配置の最適化のためにコンパイラが自動的に挿入する無意味なバイト)も、異なるアーキテクチャ間でのデータ交換時に問題を引き起こす可能性があるため、シリアライズ(構造体をバイト列に変換する)する際には注意が必要である。ネットワークバイトオーダーの適切な利用は、堅牢で互換性のあるネットワークアプリケーションを構築するための基本的な要素の一つである。