在进行网络编程时,我们经常会遇到htonl、htons、ntohl、ntohs这四个函数。这四个函数就是把主机字节序转换成网络字节序,把网络字节序转换为主机字节序。实质就是大小端模式的转换。
大端模式:是指数据的高字节保存在内存的低地址中,而数据的低字节保存在内存的高地址中,这样的存储模式有点儿类似于把数据当作字符串顺序处理:地址由小向大增加,而数据从高位往低位放。
小端模式:是指数据的高字节保存在内存的高地址中,而数据的低字节保存在内存的低地址中,这种存储模式将地址的高低和数据位权有效地结合起来,高地址部分权值高,低地址部分权值低,和我们的逻辑方法一致。
网络:是TCP/IP中规定好的一种数据表示格式,它与具体的类型、操作系统等无关,从而可以保证数据在不同主机之间传输时能够被正确解释。网络字节顺序采用big endian排序方式。
下面的代码就是将网络字节序转换为主机字节序。也就是将大端模式转换为小端模式:
-
#include <stdio.h>
-
#include <arpa/inet.h>
-
-
int main(int argc,char **argv)
-
{
-
long x = 0x12345678;
-
long y;
-
char *a = (char *)(&x);
-
printf("little endian:\n");
-
printf(" %x:%x\n %x:%x\n %x:%x\n %x:%x\n",(unsigned int)a,*a,
-
(unsigned int)(a+1),*(a+1),(unsigned int)(a+2),*(a+2),(unsigned int)(a+3),*(a+3));
-
-
y = htonl(x);
-
a = (char *)(&y);
-
printf("\nbig endian:\n");
-
printf(" %x:%x\n %x:%x\n %x:%x\n %x:%x\n",(unsigned int)a,*a,
-
(unsigned int)(a+1),*(a+1),(unsigned int)(a+2),*(a+2),(unsigned int)(a+3),*(a+3));
-
return 0;
-
}
编译执行后:
####################################################################
有些主机是采用大端模式存储,有些主机是采用小模式存储,但是具体哪些机器是采用大端模式,哪些是采用小端模式,我就没有深入去研究,如果你有兴趣,你可以去研究下。
所以我们就需要判断我们使用的机器是用大端模式还是小端,判断方法主要下面两种:
方法一:
int main(void)
{
int x = 0x11223344;
char *p = (char *)&x;
if(*p == 0x44)
{
printf("little endian\n");
}
else if(*p == 0x11)
{
printf("big endian\n");
}
return 0;
}
方法二:
-
#include
-
#include
-
-
int main(void)
-
{
-
#if __BYTE_ORDER == __LITTLE_ENDIAN
-
printf("little endian\n");
-
#endif
-
-
#if __BYTE_ORDER == __BIG_ENDIAN
-
printf("big endian\n");
-
#endif
-
-
printf("%d\n",__BYTE_ORDER);
-
-
return 0;
-
}
阅读(1638) | 评论(0) | 转发(0) |