Unix-sockets-network-byte-orders

提供:Dev Guides
移動先:案内検索

Unixソケット-ネットワークのバイト順

残念ながら、すべてのコンピューターがマルチバイト値を構成するバイトを同じ順序で保存するわけではありません。 2バイトで構成される16ビットインターネットを考えてみましょう。 この値を保存するには2つの方法があります。

  • リトルエンディアン-このスキームでは、下位バイトは開始アドレス(A)に保存され、上位バイトは次のアドレス(A+ 1)に保存されます。
  • ビッグエンディアン-このスキームでは、上位バイトは開始アドレス(A)に保存され、下位バイトは次のアドレス(A+ 1)に保存されます。

異なるバイト順序規則を持つマシンが互いに通信できるようにするために、インターネットプロトコルは、ネットワークを介して送信されるデータの標準的なバイト順序規則を指定します。 これは、ネットワークバイトオーダーと呼ばれます。

インターネットソケット接続を確立する際、sockaddr_in構造体のsin_portおよびsin_addrメンバーのデータがネットワークバイト順で表されていることを確認する必要があります。

バイト順序付け関数

ホストの内部表現とネットワークバイトオーダーの間でデータを変換するためのルーチンは次のとおりです-

Function Description
htons() Host to Network Short
htonl() Host to Network Long
ntohl() Network to Host Long
ntohs() Network to Host Short

以下は、これらの機能に関する詳細です。

  • * unsigned short htons(unsigned short hostshort)*-この関数は、16バイト(2バイト)量をホストバイト順からネットワークバイト順に変換します。
  • * unsigned long htonl(unsigned long hostlong)*-この関数は、32ビット(4バイト)量をホストバイト順からネットワークバイト順に変換します。
  • * unsigned short ntohs(unsigned short netshort)*-この関数は、16ビット(2バイト)量をネットワークバイト順からホストバイト順に変換します。
  • * unsigned long ntohl(unsigned long netlong)*-この関数は、32ビット量をネットワークバイト順からホストバイト順に変換します。

これらの関数はマクロであり、呼び出し元プログラムに変換ソースコードを挿入します。 リトルエンディアンマシンでは、コードは値をネットワークバイト順に変更します。 ビッグエンディアンのマシンでは、コードは必要ないため挿入されません。関数はヌルとして定義されています。

ホストのバイト順序を決定するプログラム

次のコードをファイル_byteorder.c_に保持し、それをコンパイルしてマシン上で実行します。

この例では、2バイト値0x0102を短整数に格納してから、連続する2つのバイトc [0](アドレスA)とc [1](アドレスA+ 1)を調べて、バイトオーダー。

#include <stdio.h>

int main(int argc, char **argv) {

   union {
      short s;
      char c[sizeof(short)];
   }un;

   un.s = 0x0102;

   if (sizeof(short) == 2) {
      if (un.c[0] == 1 && un.c[1] == 2)
         printf("big-endian\n");

      else if (un.c[0] == 2 && un.c[1] == 1)
         printf("little-endian\n");

      else
         printf("unknown\n");
   }
   else {
      printf("sizeof(short) = %d\n", sizeof(short));
   }

   exit(0);
}

Pentiumマシン上でこのプログラムによって生成された出力は次のとおりです-

$> gcc byteorder.c
$> ./a.out
little-endian
$>