字节序 byte order

本文深入探讨了字节序的概念,包括大端字节序和小端字节序的区别,并介绍了网络字节序与主机字节序之间的转换原理。此外,还讨论了不同字节序在实际编程中的应用。

我们在做网络相关的编程时,经常会遇到网络字节序和主机字节序的问题:当我们要把数据发送到网络中进行传输时,需要把数据先转换为网络字节序再发送;当我们从网络中接收到数据后,需要先转换为主机字节序才能使用。

 

Big Endian和Little Endian

字节序是计算机体系结构的一个基本属性,每台计算机都是按照自己的字节序方式处理数据的。那到底什么是字节序呢?简单的说,字节序是计算机处理数据时,对内存中数据的高位和低位进行判定的方法。字节序有两种,即大端字节序(Big Endian)和小端字节序(Little Endian)。字节序是与计算机的体系结构相关的。我们平常使用的X86平台使用的是小端字节序,而IBM的PowerPC平台使用的是大端字节序。

 

我们知道,CPU通过并行的数据总线访问内存。当CPU向内存读取数据时,首先内存中对应位中的数据被读到数据总线上,然后数据总线上的数据被存储到CPU 内部的寄存器中。每一根数据总线把内存中的一位数据传递到CPU寄存器中的一位,因此内存位与寄存器位存在对应关系。从寄存器位与内存位的对应方式可以方便的判断一台计算机所使用的字节序。

 

 


                       图1 小端字节序

 

图 1中的cpu寄存器是32位的。寄存器的最左侧是最低位(LSB,Least Significant Bit),最右侧是最高位(MSB, Most Significant Bit)。对应到内存中可知,内存的低地址字节是低位,高地址字节是高位。按照地址顺序一个字节一个字节的读出内存中的数据,我们得到0x09, 0x48, 0x14, 0x42(注意,在字节内部,高位仍然在右边)。但是把这4个字节合在一起作为一个整数读出来,结果是0x42144809。这种把低位放在低地址字节的字节序就是小端字节序。

 

 

                       图2 大端字节序

 

与小端字节序相对的就是大端字节序。与图1相反,图2中的32位寄存器中,最左侧是最高位,最右侧是最低位。图2内存中的数据与图1内存中的数据(按位地址排列)完全相同,但是按照字节一个一个的读出为0x90, 0x12, 0x24, 0x42,而把这4个字节合在一起作为一个整数读出来,结果是0x90122442。

 

2013-8 :现在看来,把字节序问题理解为CPU寄存器和内存地址之间的映射,貌似有点不太合适,不过当时确实为我提供了字节序的一种理解方法大笑

 

网络字节序和主机字节序

由于不同体系架构的设备使用的字节序不同,当他们之间联网互相发送数据时,就会产生混乱。例如要发送一个32位的整数,有的设备按照从最低位字节到最高位字节的顺序依次发送每一位数据,有的设备按照从最高位到最低位的顺序依次发送每一位数据。为了统一这种混乱,现行标准规定,所有数据在网络中传输时按照从最高位到最低位的顺序依次发送每一位数据。

 

网络设备在发送和接收数据时以字节(octect)为单位。在发送和接收单个字节时,网络设备总是按照从高位到低位的顺序发送和接收字节数据。网络设备发送和接收一个字节时,能够保证顺序正确,所以字节内部的顺序在通信过程中不用考虑。对于小端字节序主机如图1,这就意味着从右到左的顺序发送每一位;对于大端字节序主机如图2,这就意味着从左到右的顺序发送每一位。接收端也按照这个顺序接收字节中的每一位。不论双方各自的本地字节序为何,单字节数据的取值在传输前后不会发生改变。例如,图1中地址0x0100中的数据在传输到大端字节序或者小端字节序的主机后,取值仍然是0x09。


假设网卡要发送图1内存中从0x0100开始的4字节数据,网卡并不知道这4字节的数据是作为一个整数,或者仅仅是普通的字节序列。网卡简单的先把第一个字节0x09发送出去,再把第二个字节0x48发送出去,然后是0x14和0x42。接收端网卡先收到0x09,假设把它存储在地址0x0200中;然后接收到0x48,把它存储到地址0x0201中;然后是0x14和0x42,分别存储在地址0x0202和0x0203中。

 

如果上述4个字节仅仅是普通的字节序列,那么在传输前后,字节序列的顺序和取值并没有变化,没有问题。如果上述4个字节是一个整数,上述发送顺序违背了现行标准那么在大端字节序的主机和小端字节序的主机上来解释上述数值,会得出不同的数字。因此,不同字节序主机之间通信时,需要约定一种传输顺序,主机需要将上述数据的字节顺序调整为上述传输顺序后再发送。调整之前的顺序是数据在本地的表示,称作主机字节序;调整之后的顺序是数据在传输时的顺序,称作网络字节序。目前的网络字节序为大端字节序。调整之后的数据在内存中的存储情况如图3所示。

 

                       图3 小端字节序:按网络字节序排列

 

在大端字节序主机上,网络字节序和主机字节序是相同的;在小端字节序主机上,网络字节序和主机字节序是不同的。

 

位操作

如果数据不满一个比特,那么使用时需要特别小心。例如如下定义的一个结构:

如果在大端字节序主机上编译,那么high_bits的确是高4位,low_bits的确是低4位;如果在小端字节序主机上编译,那么情况就恰恰相反了。

 

 

 

 

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值