web-dev-qa-db-ja.com

整数のhtonl()とntohl()の同じ出力

リトルエンディアン[LE]マシン[Linux、Intelプロセッサ]で次のプログラムを実行しました。以下のコードスニペットで3つの出力を説明することはできません。マシンはLEであるため、aの値は_0x78563412_として格納されます。印刷時には、実際の値を表示しています。 LEマシンなので、ntohl()はノーオペレーションであり、_0x78563412_を表示することを期待しています。ただし、htonl()を含む2番目の印刷ステートメントには_0x12345678_が必要です。誰かが私が彼らが同じである理由を理解するのを手伝ってくれませんか?

_int main() 
{
    int a = 0x12345678; 

    printf("Original - 0x%x\n", (a)); 
    printf("Network - 0x%x\n", htonl(a)); 
    printf("Host - 0x%x\n", ntohl(a)); 

    return 0;
}
_

出力:

_Original - 0x12345678
Network - 0x78563412
Host - 0x78563412
_
11
Bhaskar

LEマシンなので、ntohl()は何もしないと思います

それは間違いです。ネットワークのバイト順序はビッグエンディアン、ホストのバイト順序はリトルエンディアンです。したがって、ntohlhtonlはどちらも、入力のバイトスワップバージョンを返します。

htonlのポイントは、ホストで整数を取り、次のように書くことができるということです。

_int i = htonl(a);
_

その結果、iのメモリネットワークバイトオーダーを使用して解釈した場合は、aと同じ値になります。したがって、iのオブジェクト表現をソケットに書き込み、もう一方のエンドのリーダーがネットワークバイトオーダーの4バイト整数を期待する場合、aの値を読み取ります。

_0x78563412_を表示します

これはあなたが書くつもりだったものですか? ntohlがno-op(つまり、恒等関数)の場合、ntohl(a) == aがあるため、3行目は必ず1行目と同じものを出力します。これは、プログラムが出力するビッグエンディアンの実装で発生することです。

_Original - 0x12345678
Network - 0x12345678
Host - 0x12345678
_
23
Steve Jessop

htonlntohlはまったく同じ関数です。それらはhtonl(ntohl(x)) == xを満たすことになっています。それらは、ドキュメントのためだけに異なる名前が付けられています(同じであっても、ホストからネットワークへ、またはその逆に変換することを明示します)。したがって、リトルエンディアンのマシンでは、どちらもバイトスワッピングを実行し、ビッグエンディアンのマシンでは、どちらもノーオペレーションです。

12
Alok Singhal

aを値で渡しているため、これらの関数のいずれによっても変更されません。

htonl()ntohl()returningであるものを出力しています。

編集して追加:私はあなたが1つがノーオペレーションだと思ったところを逃しました。そうではありません。どちらもLEマシンでまったく同じことをします。バイト順序を逆にします。 ntohl()は、intの順序でネットワークバイトを渡すことを期待しています。

5
Brian Roach

プログラムで_int a;_ yoと書くと、aにホスト順の整数が含まれていることがわかりますが、プログラムはそれを認識していません。ネットワークの順序で値がすでに含まれているintを簡単に指定できます。もちろん、ホストの順序にない値に対して算術演算子を使用すると、ネットワークの順序がホストの順序と同じでない場合、ネットワークの観点からは結果が不正確になります。

しかし、これは今のところフェッチされていません。ネットワークで順序付けられた値は、送信前または受信直後に、低レベルの構造で正確にそのように保持されることがよくあります。

プログラムの何が問題なのかというと、ntohl()を呼び出すと、提供しているintがネットワークのメモリに格納されている値であるというntohl()関数を約束しているということです。注文。それが契約です。それが真実でない場合、関数はあなたが期待することを実行しません、そしてそれはあなたが狙っているものです。

他のほとんどのシステムで説明されているように(大きなまたは小さなが愚かなエンディアンではない)、2つの関数は通常同じであり、バイトが逆になるか、操作がありません。

0
kriss