htonl打印垃圾值

时间:2012-10-19 08:42:06

标签: c sockets unix

变量'value'是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

请说明原因可能是什么?

4 个答案:

答案 0 :(得分:2)

主机订单是您的机器正确理解数据(假设您的机器是小端)的顺序。网络订单是Big Endian,您的系统无法正确理解。这就是你所谓的垃圾值的原因。

所以,基本上,代码没有任何内容。 :)

Google“Endianness”获取有关Big Endian和Little Endian的所有详细信息。

提供更多信息,在Big endian中,第一个字节或最低地址将具有最高有效字节,在小端,在同一位置,将存在最低有效字节。因此,当您使用htonl时,您的第一个字节现在将包含最重要的字节,但您的系统会将其视为最不重要的字节。

考虑到大端的十进制1000(十六进制3E8)的维基百科示例将是03 E8,而小端将是E8 03.现在,如果你将03 E8传递给一台小机器,它将被认为是十进制59395。

答案 1 :(得分:2)

我猜你的输入是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

答案 2 :(得分:1)

htonl() and htons()是用于将数据从主机的endianess转换为网络耐用的函数。

网络使用big-endian。所以如果你的系统是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;
}

它将在X86_64上打印After htonl():0x78563412 , 0x7856

参考:

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

答案 3 :(得分:0)

@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
相关问题