字节序
字节序,即字节在电脑中存放时的序列与输入(输出)时的序列,是先到的在前,还是后到的在前。
常见序:
1. LE Little endian: 最符合人的思维的字节序,将低序字节存储在起始地址,地址低位存储值的低位,地址高位存储值的高位
2. BE big-endian:最直观的字节序,地址低位存储值的高位,地址高位存储值的低位。
例子:在内存中双字 0x01020304 的存储方式
内存地址: 4000&4001&4002&4003
LE: 04 03 02 01
BE: 01 02 03 04
x86系列CPU都是little-endian的字节序
为了进行转换 bsd socket提供了转换的函数 有下面四个:
- htons 把unsigned short类型从主机序转换到网络序
- htonl 把unsigned long类型从主机序转换到网络序
- ntohs 把unsigned short类型从网络序转换到主机序
- ntohl 把unsigned long类型从网络序转换到主机序
案例1: 如何手算主机字节顺序转换为网络字节顺序?
假设某16位的整数,主机字节顺序的值是21,那么它的网络字节顺序是多少? 解决的步骤是:
1、将21化成二进制,二进制,如果不足16位就在其前面补0,补满16位。
21转换成二进制是:10101,在它前面补0,补满16位后就得到:00000000#00010101
2、将这个16位二进制字符平分成两段,每段8位
0000000 000010101 == > 00000000#00010101
3、颠倒这两段的顺序,然后去掉第一个字符“1”前面的0,化成十进制就得到了网络字节顺序的值了。
00000000#00010101颠倒后:00010101#00000000
即00 01 01 01 00 000000
去掉第一个“1”前面的0得到:1 01 01 00 000000
化成十进制得到:5376
也就是说,虽然整体顺序改变了,但是也仅是整体顺序改变了,每个字节中的顺序并没有变化,如果不明白这就话的意思的话,再看例子:
例子1:如果我们将0x1234abcd写入到以0x0000开始的内存中,则结果为
big-endian little-endian
0x0000 0x12 0xcd
0x0001 0x23 0xab
0x0002 0xab 0x34
0x0003 0xcd 0x12
big-endian little-endian
0x0000 0x12 0xcd
0x0001 0x23 0xab
0x0002 0xab 0x34
0x0003 0xcd 0x12
例子2:变量
x
类型为int
,位于地址0x100
处,它的十六进制为0x01234567
,地址范围为0x100~0x103
字节,其内部排列顺序依赖于机器的类型。大端法从首位开始将是:
0x100: 01, 0x101: 23,..
。而小端法将是:
0x100: 67, 0x101: 45,..
。PS: 这里注意啦,小端的时候,0X100这个字节存储的是67,而不是76,也就是说颠倒是以字节为单位的,在一个字节的内部,顺序是不会颠倒的。