変数「値」は uint32_t です
value = htonl(value);
printf("after htonl is %ld\n\n",value);
This prints -201261056
value = htons(value);
printf("after htons is %ld\n\n",value);
This prints 62465
何が原因か教えてください。
ホスト順序は、マシンがデータを正しく理解する順序です(マシンがリトルエンディアンであると想定)。ネットワークの順序はビッグエンディアンであり、システムが正しく理解することはできません。これが、いわゆるガベージ値の理由です。
したがって、基本的に、コードには何もありません。:)
ビッグエンディアンとリトルエンディアンに関するすべての詳細を取得するためのGoogleの「エンディアン」。
さらに情報を提供します。ビッグエンディアンでは、最初のバイトまたは最下位アドレスが最上位バイトを持ち、リトルエンディアンでは、同じ場所に最下位バイトが存在します。したがって、htonlを使用すると、最初のバイトに最上位バイトが含まれるようになりますが、システムはそれを最下位バイトと見なします。
ウィキペディアのビッグエンディアンの10進数1000(hex 3E8)の例を考えると03 E8になり、リトルエンディアンの10進数はE8 03になります。ここで、03 E8を小さなマシンに渡すと、10進数の59395と見なされます。
あなたの入力は 500 だと思いますね。
500 は 2* 8+2 *7+2* 6+2 *5+2* 4+2 *2 または0x00 0x00 0x01 0xF4
リトルエンディアン順です。
TCP/IP はビッグ エンディアンを使用します。したがって、htonl の後のシーケンスは0xF4 0x01 0x00 0x00
.
符号付き整数として出力すると、最初の桁が 1 であるため、負になります。負の数は補数と見なされます. 値は -(2* 27 + 2 *25+2* 24+2 *23+2* 22+2 *21+2* 20+2 *19+2* 18+2 * 17+2**16) == -201261056
htonl() and htons()
データをホストのエンディアンからネットワークのエンディアンに変換するために使用される関数です。
ネットワークはビッグエンディアンを使用します。したがって、システムがX86の場合、それはリトルエンディアンです。
ホストからネットワークへのバイトオーダー(長いデータ)はhtonl()です。つまり、32ビット値をネットワークバイトオーダーに変換します。
ホストからネットワークへのバイトオーダー(ショートデータ)はhtons()です。つまり、16ビット値をネットワークバイトオーダーに変換します。
htonl()がどのように機能するか、およびhtons()関数で32ビット値を使用した場合の効果を示すサンプルプログラム。
#include <stdio.h>
#include <arpa/inet.h>
int main()
{
long data = 0x12345678;
printf("\n After htonl():0x%x , 0x%x\n", htonl(data), htons(data));
return 0;
}
After htonl():0x78563412 , 0x7856
X86_64で印刷 されます。
参照:
http://en.wikipedia.org/wiki/Endianess
http://msdn.microsoft.com/en-us/library/windows/desktop/ms738557%28v=vs.85%29.aspx
http://msdn.microsoft.com/en-us/library/windows/desktop/ms738556%28v=vs.85%29.aspx
@halfelf>I jut want to put my findings.I just tried the below program with the same
value 500.I guess you have mistakenely mentioned output of LE as BE and vice versa
Actual output i got is 0xf4 0x01 0x00 0x00 as little Endian format.My Machine is
LE
#include <stdio.h>
#include <netinet/in.h>
/* function to show bytes in memory, from location start to start+n*/
void show_mem_rep(char *start, int n)
{
int i;
for (i = 0; i < n; i++)
printf(" %.2x-%p", start[i],start+i);
printf("\n");
}
/*Main function to call above function for 0x01234567*/
int main()
{
int i = 500;//0x01234567;
int y=htonl(i); --->(1)
printf("i--%d , y---%d,ntohl(y):%d\n",i,y,ntohl(ntohl(y)));
printf("_------LITTLE ENDIAN-------\n");
show_mem_rep((char *)&i, sizeof(i));
printf("-----BIG ENDIAN-----\n");/* i just used int y=htonl(i)(-1) for reversing
500 ,so that
i can print as if am using a BE machine. */
show_mem_rep((char *)&y, sizeof(i));
getchar();
return 0;
}
output is
i--500 , y----201261056,ntohl(y):-201261056
_------LITTLE ENDIAN-------
f4-0xbfda8f9c 01-0xbfda8f9d 00-0xbfda8f9e 00-0xbfda8f9f
-----BIG ENDIAN-----
00-0xbfda8f98 00-0xbfda8f99 01-0xbfda8f9a f4-0xbfda8f9b