16

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

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
4

4 に答える 4

26

LEマシンなのでntohl()、ノーオペレーションになると思います

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

重要なのhtonlは、ホスト上で整数を取り、次のように書くことができるということです。

int i = htonl(a);

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

と表示0x78563412

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

Original - 0x12345678
Network - 0x12345678
Host - 0x12345678
于 2012-07-10T23:15:15.023 に答える
18

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

于 2012-07-10T23:15:38.717 に答える
6

値を渡すためa、これらの関数のいずれによっても変更されないためです。

あなたは何htonl()を印刷していてntohl()戻ってきています。

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

于 2012-07-10T23:13:40.353 に答える
0

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

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

あなたのプログラムの何が悪いのかというと、あなたがあなたが提供している関数ntohl()にあなたが約束しているのは、ネットワークの順序でメモリに保存されている値であるということです。それが契約です。それが正しくない場合、関数は期待どおりに機能しません。それがあなたが狙っている目的です。ntohl()int

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

于 2014-10-31T16:45:54.600 に答える