バイトオーダってなに?
TCPソケットに関して調べているときに出くわしたバイトオーダに関する備忘録。
sockaddr_in構造体に値を格納するときに気になることを発見したのがきっかけです。
多バイトデータのメモリ上の配置順
たとえば"1234ABCD"なる4バイトのデータをメモリ上に配置する際に
- バイト上位からメモリに配置(12 34 AB CD)するのがビッグエンディアン
- バイト下位からメモリに配置(CD AB 34 12)するのがリトルエンディアン
ということ。
どんなときに使うのか?
マシンのアーキテクチャによってビッグエンディアンを採用しているものとリトルエンディアンを用いるものがあるため、同一ホスト内での運用ならあまり影響ないがネットワーク上でのデータ交換やシステムの移行などの場合で問題が発生する恐れがある。
ゆえにTCP/IPネットワークを利用するときはビッグエンディアンを使用すること!と決まっている。(いわゆるネットワークバイトオーダ)
変換の必要が発生したときは
今回調べる経緯にもなったTCPソケットにおけるsockaddr_in構造体へのデータ格納。
そこでも使用されていた
htonl(INADDR_ANY)
という記述。
- htonl→host to network longの略(longは4ビットの整数型)
- htons→host to network shortの略(shortは2ビットの整数型)
があり、ネットワークバイトオーダ(ビッグエンディアン)に変換するための関数が使用されているということ。※もともとホストがビッグエンディアンであれば何もしない。
ちなみに
- ntohl→network to host long
- ntohs→network to host short
にて必要に応じて「ネットワークバイトオーダをローカルのバイトオーダへ」変換可能。※こちらもホストがビッグエンディアンなら何もしない。
まとめ
ソケットに関するコードをいくつか眺めていると必ずと言っていいほどでてきたhtonl関数ですが、バイトオーダなる言葉すら知らなかったため理解するのにとても苦労しました。
今まで普通にパソコンを構っていてもメモリ上のデータの配置なんて気にすることありませんでしたし、サーバの設定も手順を追っかけるばかりでそこまで気が周ってませんでした。
いい機会だと思って少し真面目に調べた結果
- データをメモリに格納する際、バイト上位から記録するものと下位から記録するものがある
- 上位からをビッグエンディアン、下位からをリトルエンディアンという
- マシンのアーキテクチャによって採用されるバイトオーダは異なる
- ネットワーク上には様々なホストが存在するため、ビッグエンディアンを用いるルールになっている。これがネットワークバイトオーダ。
などがわかりました。知ってる人にとっては常識なんでしょうが、知らない人間にとってはなんのことやらサッパリ…という感じ。