字节序

字节序是指多字节数据在计算机内存中存储或者网络传输时各字节的存储顺序。


主机字节序:

不同的CPU有不同的字节序类型,这些字节序是指整数在内存中保存的顺序,这个叫做主机字节序。
最常见的有两种:
1. Little endian:就是低位字节排放在内存的低地址端即该值的起始地址,高位字节排放在内存的高地址端。

2. Big endian:就是高位字节排放在内存的低地址端即该值的起始地址,低位字节排放在内存的高地址端。

 

网络字节序:

网络字节顺序是TCP/IP中规定好的一种数据表示格式,它与具体的CPU类型、操作系统等无关,从而可以保证数据在不同主机之间传输时能够被正确解释。

网络字节顺序采用Big endian排序方式,即大端字节序。 


为了进行转换,bsd socket提供了转换的函数,有下面四个:
htons 把unsigned short类型从主机序转换到网络序
htonl 把unsigned long类型从主机序转换到网络序
ntohs 把unsigned short类型从网络序转换到主机序
ntohl 把unsigned long类型从网络序转换到主机序

 注:在使用little endian的系统中,这些函数会把字节序进行转换 。

         在使用big endian类型的系统中,这些函数会定义成空宏。

 

同样 在网络程序开发时 或是跨平台开发时 也应该注意保证只用一种字节序,不然两方的解释不一样就会产生bug.

 

举个简单的例子,如果我们将0x1234abcd写入到以0x0000开始的内存中,则结果为

           big-endian     little-endian
0x0000   0x12         0xcd
0x0001   0x34         0xab
0x0002   0xab         0x34
0x0003   0xcd         0x12


字节序测试程序 

不同cpu平台上字节序通常也不一样,下面写个简单的C程序,它可以测试不同平台上的字节序。

#include <stdio.h>

#include <netinet/in.h>

int main()

{

    int i_num = 0x12345678;

    printf("[0]:0x%x\n", *((char *)&i_num + 0));

    printf("[1]:0x%x\n", *((char *)&i_num + 1));

    printf("[2]:0x%x\n", *((char *)&i_num + 2));

    printf("[3]:0x%x\n", *((char *)&i_num + 3));

10 

 

11 

    i_num = htonl(i_num);

12 

    printf("[0]:0x%x\n", *((char *)&i_num + 0));

13 

    printf("[1]:0x%x\n", *((char *)&i_num + 1));

14 

    printf("[2]:0x%x\n", *((char *)&i_num + 2));

15 

    printf("[3]:0x%x\n", *((char *)&i_num + 3));

16 

 

17 

    return 0;

18 


在80X86CPU平台上,执行该程序得到如下结果: 
[0]:0x78 
[1]:0x56 
[2]:0x34 
[3]:0x12

[0]:0x12 
[1]:0x34 
[2]:0x56 
[3]:0x78

分析结果,在80X86平台上,系统将多字节中的低位存储在变量起始地址,使用小端法。htonl将i_num转换成网络字节序,可见网络字节序是大端法。


程序:写一个C函数,若处理器是Big_endian,则返回 0;若是Little_endian,则返回1;

int  checkSystem()

{

union check

{

int i;

char ch;

}test;

test.i  = 1;

return (test.ch == 1);

}

这是利用union数据类型的特点编写的程序,是不是对你很有启发。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值