网络字节序与主机字节序

网络字节序与主机字节序

大部分IT人员在实际的开发中都很少会直接和字节序打交道。只有有在跨平台以及网络程序中字节序才是一个应该被考虑的问题。

字节序:   顾名思义字节的顺序,即字节在电脑中存放时的序列与输入(输出)时的序列是先到的在前还是后到的在前。

主机字节序和网络字节序

在所有的介绍字节序的文章中都会提到字节序分为两类:Big-EndianLittle-Endian,即大端模式和小端模式。

引用标准的Big-EndianLittle-Endian的定义如下:

Little-Endian: 就是低位字节排放在内存的低地址端,高位字节排放在内存的高地址端。

Big-Endian  就是高位字节排放在内存的低地址端,低位字节排放在内存的高地址端。

网络字节顺序NBONetwork Byte Order

按从高到低的顺序存储,所以Big-Endian又称网络字节序,在网络上使用统一的网络字节顺序,可以避免兼容性问题。

主机字节顺序(HBOHost Byte Order

不同的机器主机字节序不相同,与CPU设计有关计算机数据存储有两种字节优先顺序:高位字节优先和低位字节优先。所以主机字节序存放方式有两种Big-EndianLittle-Endian

在不同的CPU上运行不同的操作系统,字节序也是不同的,常见的参见下表。

处理器 操作系统               字节排序

Alpha 全部                      Little endian

HP-PA NT                       Little endian

HP-PA UNIX                   Big endian

Intelx86 全部                   Little endian <-----x86系统是小端字节序系统

Motorola680x()               全部 Big endian

MIPS NT                         Little endian

MIPS UNIX                     Big endian

PowerPC NT                   Little endian

PowerPC NT                Big endian <-----PPC系统是大端字节序系统

RS/6000 UNIX                 Big endian

SPARC UNIX                   Big endian

IXP1200 ARM核心           全部 Little endian

Internet上数据以高位字节优先顺序在网络上传输,即大端字节序,所以对于在内部是以低位字节优先方式存储数据的机器(即按小端字节序存放的数据的机器,x86 系列 CPU 都是 little-endian 的字节序),在Internet上传输数据时就需要进行转换。

 

大端字节序和小端字节序如何在内存中存放

对大端字节序和小端字节序有一定的了解后,我们来看一下大端字节序和小端字节序是在内存中是怎样存放的。

大端字节序

在内存中,栈底是低地址位、栈顶是高地址位

例如字节序0x12345678这个16进制数在内存中以大端字节序方式存放就是这样的:

内存地址   存放内容

高地址

--------------------------

0x4003     0x78(低位)

0x4002     0x56

0x4001     0x34

0x4000     0x12(高位)

--------------------------

低地址

 

只需要把内存地址从左到右按照由低到高的顺序写出,那么0x12345678这个16进制数以大端字节序存放的序列就是12345678,与我们平时看到的一样,非常直观,不要考虑任何对应关系,所以大端字节序是非常符合人们平时的思维的。

 

       小端字节序

与大端字节序在内存中的存放方式正好相反,还是以16进制数0x12345678为例,在内存中以小端字节序存放的方式是这样的:

内存地址   存放内容

高地址

--------------------------

0x4003     0x12(高位)

0x4002     0x34

0x4001     0x56

0x4000     0x78(底位)

--------------------------

低地址

将内存地址从左到右按照由低到高的顺序写出,那么0x12345678这个16进制数以小端字节序存放的序列就是78563412,与大端字节序是相反的。如果一个数0x8060在内存中占4个字节,那么它按大端字节序存放的序列就是 00 00 80 60,如果是按小端字节序的话就是60 80 00 00,所以我之前说大小端字节序未转换可能会各别字段值偏大。

 

总的来说大端字节序和小端字节序存储的特点就是

Little  endian : 将低序字节存储在起始地址,及底地址优先存储,与人们常有存储数据思维方式相反。

Big  endian :  将高序字节存储在起始地址,及高地址优先存储,符合人们常有思维。

 

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

【用函数判断系统是Big Endian还是Little Endian
//
如果字节序为big-endian,返回true;
//
反之为   little-endian,返回false

int IsMyMachineBigEndian()

{

       unsigned short test = 0x1122;

       unsigned char  *cp = &test;   //使cp指向test的地址;

       return (*cp == 0x11);         //如果cp所指向的地址值为0x11,则说明高字节

0x11存放在起始地址,那么就是大端字节序,

否则就是小端字节序。

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值