コンピュータの発展の歴史において、データの保存方法には統一された標準は存在しませんでした。 バイトの並び方は2つの一般的なルールに従っていました。例えば、ある多桁数の低いバイトを小さいアドレスに、高いバイトを大きいアドレスに配置する場合、これを小端序と呼びます。その逆の場合、大端序と呼びます。ネットワークアプリケーションにおいては、バイトオーダーは考慮すべき重要な要素であり、異なる種類のコンピュータが異なる標準のバイトオーダーを採用している可能性があるため、すべてネットワーク標準に変換されます。 読解習慣に従うと、大端バイトオーダーは左から右への読み込み順序に合致します。
プロセッサアーキテクチャ
- x86、MOS Technology 6502、Z80、VAX、PDP-11などのプロセッサは小端序を採用
- Motorola 6800、Motorola 68000、PowerPC 970などのプロセッサは大端序を採用
- ARM、PowerPC(PowerPC 970を除く)、DEC Alpha、SPARC V9、MIPS、PA-RISCおよびIA64のバイトオーダーは可変式
网络序
ネットワーク転送では一般的に大端序が採用され、ネットワークバイト序とも呼ばれ、ネットワーク序とも言います。IPプロトコルにおいて大端序はネットワークバイト序として定義されています。
Berkeley
ソケットは、16ビットおよび32ビット整数をネットワーク序とホストバイト序間で変換するための変換関数群を定義しています。
#include <arpa/inet.h>
uint32_t htonl(uint32_t hostlong); // uint32_t をネットワーク序に変換
uint16_t htons(uint16_t hostshort); // uint16_t をネットワーク序に変換
uint32_t ntohl(uint32_t netlong); // uint32_t をネットワーク序からホスト序へ変換
uint16_t ntohs(uint16_t netshort); // uint16_t をネットワーク序からホスト序へ変換
asio
をネットワークライブラリとして使用する場合、組み込みの名前空間には、クロスプラットフォームに対応した関数名が用意されています。
- boost::asio::detail::socket_ops::network_to_host_long
- boost::asio::detail::socket_ops::network_to_host_short
- boost::asio::detail::socket_ops::host_to_network_long
- boost::asio::detail::socket_ops::host_to_network_short
Visual Studio デバッガー
デバッグモードでは、デバッグメニューを選択し、ウィンドウからメモリウィンドウにチェックを入れます。
Visual Studio では、デバッガー内で直接メモリ内のデータを表示できます(下記画像参照)。
メモリの確認方法
- ウィンドウから直接変数名を表示し、対応する変数のアドレスにジャンプ
- 変数が元のポインタ型である場合、ウィンドウで変数をダブルクリックして選択し、メモリウィンドウにドラッグすることで、対応する内容のアドレスを表示
- 変数がポインタ型でない場合は、計算ウィンドウに追加し、アドレスを取得してから、手動でメモリウィンドウにコピー
例を挙げて説明します
データを受信し、buffer
オブジェクトに格納します。ネットワークバイトオーダーをホストバイトオーダーに変換し、body_length
が30になります。サーバー側では、このデータを送信するために4バイトを使用します。
bool NetworkMessage::decode_header()
{
// ネットワークバイトオーダーをホストバイトオーダーに変換
body_length_ = boost::asio::detail::socket_ops::network_to_host_long(*(int *)buffer_.data());
return auto_reserve(body_length_);
}
大端型バイトオーダー: メモリウィンドウ内のbuffer_
の内容を観察します。
小端型バイトオーダー: メモリウィンドウ内のbody_length_
の内容を観察します。