天下

记录修行的印记

字节顺序:高位优先(big-endian)和低位优先(little-endian)

 

字节顺序是指占内存多于一个字节类型的数据在内存中的存放顺序,通常有小端、大端两种字节顺序。

小端字节序指低字节数据存放在内存低地址处,高字节数据存放在内存高地址处;

大端字节序是高字节数据存放在低地址处,低字节数据存放在高地址处。

基于X86平台的PC机是小端字节序的

网络字节序: MSB 高字节前存法 Most Significant Bit   (Big Edian)

主机字节序: LSB 低字节前存法 Lest Significant Bit  (Little Edian)


    因为现行的计算机都是以八位一个字节为存储单位,那么一个16位的整数,也就是C语言中的short,在内存中可能有两种存储顺序big-endian和litte-endian。考虑一个short整数0x3132(0x32是低位,0x31是高位),把它赋值给一个short变量,那么它在内存中的存储可能有如下两种情况:



可以做个实验
在Windows上下如下程序
#include 
<stdio.h>
#include 
<assert.h>

int main(void)
{
        
short test;
        FILE
* fp;
         
        test 
= 0x3132/* (31ASIIC码的'1', 32ASIIC码的'2') */
        
if ((fp = fopen("c:\\test.txt""wb")) == NULL)
              assert(
0);
        fwrite(
&test, sizeof(short), 1, fp);
        fclose(fp);
        
return 0;
}

    然后在C盘下打开test.txt文件,可以看见内容是21,而test等于0x3132,可以明显的看出来x86的字节顺序是低位在前。如果我们把这段同样的代码放到(big
-endian)的机器上执行,那么打出来的文件就是12。这在本机中使用是没有问题的。但当你把这个文件从一个big-endian机器复制到一个little-endian机器上时就出现问题了。
    如上述例子,我们在big
-endian的机器上创建了这个test文件,把其复制到little-endian的机器上再用fread读到一个short里面,我们得到的就不再是0x3132而是0x3231了,这样读到的数据就是错误的,所以在两个字节顺序不一样的机器上传输数据时需要特别小心字节顺序,理解了字节顺序在可以帮助我们写出移植行更高的代码。


正因为有字节顺序的差别,所以在网络传输的时候定义了所有字节顺序相关的数据都使用big
-endian,BSD的代码中定义了四个宏来理:
#define ntohs(n)      //网络字节顺序到主机字节顺序 n代表net, h代表host, s代表short
#define htons(n)      //主机字节顺序到网络字节顺序 n代表net, h代表host, s代表short
#define ntohl(n)      //网络字节顺序到主机字节顺序 n代表net, h代表host, s代表long
#define htonl(n)      //主机字节顺序到网络字节顺序 n代表net, h代表host, s代表long

posted on 2011-02-28 13:07 天下 阅读(6874) 评论(0)  编辑 收藏 引用 所属分类: C/C++Socket


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理


<2013年3月>
242526272812
3456789
10111213141516
17181920212223
24252627282930
31123456

导航

统计

常用链接

留言簿(4)

随笔分类(378)

随笔档案(329)

链接

最新随笔

搜索

最新评论