2

变量“值”是 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

4 回答 4

2

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

因此,基本上,代码没有任何内容。:)

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

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

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

于 2012-10-19T08:44:55.350 回答
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

于 2012-10-19T09:12:43.743 回答
1

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

网络使用大端序。因此,如果您的系统是 X86,那么它是 little-endian。

主机到网络字节顺序(长数据)是 htonl()。ie 将 32 位值转换为网络字节顺序。

主机到网络字节顺序(短数据)是 htons()。ie 将 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

于 2012-10-19T08:55:32.417 回答
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
于 2013-05-08T13:02:05.820 回答