[BlueLeaf1336]> PROGRAM> WinSock勉強会>

WinSockの基本 -- その4

historyTOP

2002/12/03:作成
2002/12/04:更新
2004/02/09:整理

ネットワークバイトオーダTOP

ネットワークでのデータの形式を、ネットワークバイトオーダという。 「こけるWired」での説明では、コンピュータによる数値の取り扱いに関して、 次の2種類がある。

「ビッグエンディアン」は、「大きな桁が先」にあり、 「リトルエンディアン」は、「小さな桁が先」にある。

$1234をメモリに格納する場合
ビッグエンディアン$34 $12
リトルエンディアン$12 $34

の順になるそうだ。 で、「ネットワークバイトオーダ」は、どっちなのかというと、「ビッグエンディアン」の方である。なぜかは知らない。 で、IntelのCPUでは「リトルエンディアン」だそうだ。なぜかは知らない。

つまり、変換する必要がある。どうやってか?

これも、次のような関数が用意されている。4つである。

4つとはいえ、htonlntohlは同じものらしい。 まあ、前と後を入れ替えるだけなんだからあたりまえといえばあたりまえだ。

{$EXTERNALSYM htonl}
function htonl(hostlong: u_long): u_long; stdcall;

host to net long」で、ホスト形式のデータをネットワーク形式に変換(LongInt版)。

{$EXTERNALSYM htons}
function htons(hostshort: u_short): u_short; stdcall;
host to net short」で、ホスト形式のデータをネットワーク形式に変換(SmallInt版)。
{$EXTERNALSYM ntohl}
function ntohl(netlong: u_long): u_long; stdcall;
net to host long」で、ネットワーク形式のデータをホスト形式に変換(LongInt版)。
{$EXTERNALSYM ntohs}
function ntohs(netshort: u_short): u_short; stdcall;
net to host short」で、ネットワーク形式のデータをホスト形式に変換(SmallInt版)。 使ってみよう。

エンディアン変換テストTOP

こんな感じで。

procedure TForm1.Button11Click(Sender: TObject);
var
    ul, hst_ul, net_ul: u_long;
    us, hst_us, net_us: u_short;
begin
    ul     := 2023406814;
    net_ul := htonl(ul);
    hst_ul := ntohl(net_ul);

    us     := 30874;
    net_us := htons(us);
    hst_us := ntohs(net_us);

    ShowMessage(IntToHex(ul, 1));
    ShowMessage(IntToHex(net_ul, 1));
    ShowMessage(IntToHex(hst_ul, 1));

    ShowMessage(IntToHex(us, 1));
    ShowMessage(IntToHex(net_us, 1));
    ShowMessage(IntToHex(hst_us, 1));
end;

最初、IntToStrにしていたが、もうひとつわかりにくかったので、IntToHexにした。特に何かを理解しているわけではない。 適当に思い出したものを使ってみたら、入れ替わってる様子がよくわかったので、これで。

コード表示結果備考
IntToHex(ul, 1)789ABCDEPentium!!!なので、リトル(略)
IntToHex(net_ul, 1)DEBC9A78ビッグ>リトル変換
IntToHex(hst_ul, 1)789ABCDEリトル>ビッグ変換
IntToHex(us, 1)789APentium!!!なので、リトル(略)
IntToHex(net_us, 1)9A78ビッグ>リトル変換
IntToHex(hst_us, 1)789Aリトル>ビッグ変換

ちなみに、IntToHexは、stringで返してくれる。 それから、コード中のテスト用数値(ul,usに代入したもの)は、16進表記でよさげなものを選んだ。

で、確かに入れ替わっているけどなんか気持ち悪いようなそうでないような。 4桁分をひとまとめにしたもののうち、左2桁、右2桁が入れ替わっている。 確かに入れ替わっているので、今日はここまで。

2002/12/04

ふと思ったが、Pen!!!がリトルエンディアンだというなら、すでに入れ替わっているはず。なのに、見た目は普通(大きなほうの桁がちゃんと左側にある)。 でも逆だと見にくいので、OSかDelphiが入れ替えて見せてくれてるんだろう。多分。 それをビッグエンディアンに変えたら、もともとひっくり返して見せてるものをひっくり返すからひっくり返ったように見えてしまうんだろう。

EOFTOP