1. 字节序
字节序即字节的存储顺序,如果数据都是单字节的,那怎么存储无所谓了,但是对于多字节数据,比如int,double等,就要考虑存储的顺序了。字节序是硬件层面的东西,通常只和你使用的处理器架构有关,而和编程语言无关。字节序分为大端序和小端序。
大端序:数据的高位字节存放在地址的低端 低位字节存放在地址高端。
小端序:数据的高位字节存放在地址的高端 低位字节存放在地址低端。
下面两张图分别表示了数字0x12345678在大端机和小端机中的存储。
图1 大端序
图2 小端序
2. 比特序
字节序是一个对象中的多个字节之间的顺序问题,比特序就是一个字节中的8个比特位(bit)之间的顺序问题。一般情况下系统的比特序和字节序是保持一致的。以二进制数值10110101为例,其在不同平台下的内存位序如下:
大端的含义是数值的最高位1(最左边的1)放在了内存起始位置上,即数值10110101的大端内存布局为10110101。
小端的含义是数值的最低位1(最右边的1)放在了内存起始位置上,即数值10110101的小端内存布局为10101101。
3.位域
对于位域有一个约定:在C语言的结构体中如果包含了位域,如果位域A定义在位域B之前,那么位域A总是出现在低地址的比特位。 这就决定了网络编程中位域在定义时必须处理大小端问题。(同样,结构体中前面的成员也处于较低的地址)
对于IP头,可以这样理解,网络传输时version在前,ihl在后,网络是大端序,可以认为version是数字的高位,ihl是低位,所以:
在大端机中,由于低地址是高位,所以位域version必须在前面;
在小端机中,由于高地址是高位,所以位域version必须在后面。
struct iphdr {
#if defined(__LITTLE_ENDIAN_BITFIELD)
__u8 ihl:4,
version:4;
#elif defined (__BIG_ENDIAN_BITFIELD)
__u8 version:4,
ihl:4;
#else
#error "Please fix <asm/byteorder.h>"
#endif
__u8 tos;
__be16 tot_len;
__be16 id;
__be16 frag_off;
__u8 ttl;
__u8 protocol;
__sum16 check;
__be32 saddr;
__be32 daddr;
/*The options start here. */
};
Transmitting the Frame (byte order and bit order)
Ethernet transmission is strange, in that the byte order is big-endian (leftmost byte is sent first), but bit order little-endian (rigthmost, or LSB (Least Significant Bit) of the byte is sent first). For example, if you are sending a frame:
<---
We assume the preamble has been sent, then the next to be sent is the destination MAC address - 6 bytes, but for this example we will show the first 4 bytes:
11100001 00001111 10101010 10010011
Byte1 Byte2 Byte3 Byte4
The data normally moves to the left, using traditional images of frames. This is true for each of the 4 bytes - they will be transmitted in big-endian, meaning "left byte first". But we must reverse the bits in each byte, to show the actual serial stream of bits moving to the left. So the actual bits being transmitted to the left, are as follows with the bits in each byte reversed:
< 10000111 11110000 01010101 11001001
Byte1 Byte2 Byte3 Byte4
(reversed) (reversed) (reversed) (reversed)
NOTE: Ethernet does not group bytes. It has no idea that it is sending a 6-byte address, or a 2-byte Type, etc. It simply sends the entire frame, one byte at a time, from left to right, with each byte being sent LSB first and MSB last.
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)