这是linux对IP头的定义 /usr/include/linux/ip.h 或 linux/include/linux/ip.h)
- struct iphdr {
- #if __BYTE_ORDER == __LITTLE_ENDIAN
- uint8_t ihl:4,
- version:4;
- #elif __BYTE_ORDER == __BIG_ENDIAN
- uint8_t version:4,
- ihl:4;
- #endif
- uint8_t tos;
- uint16_t tot_len;
- uint16_t id;
- uint16_t frag_off;
- uint8_t ttl;
- uint8_t protocol;
- uint16_t check;
- uint32_t saddr;
- uint32_t daddr;
-
- };
版本号和首部长度是同一个字节的,这也要区分大端小端吗?我一直以为大端小端是字节间顺序的问题,不是字节内部位顺序的问题。网络数据发送时是字节流还是位流?发送时uint16_t和uint32_t的高字节必需先发送,那么同一字节的高位先发送还是低位?我找不到gcc讲结构位定义的文档,有链接么?
可以这样来解释,
1)从道理上来说,little endian中的位应该这样排列:
01234567
即排在前面的是低位。因此,先分配least significant bits
2)而在Big endian中,位应该这样排列:
76543210
即排在前面的是高位。因此,先分配most significant bits。
可以这样来理解,
1)在Big Endian的情况下,"排在前面的是高位"
a. 对于顺序的两个字节来说,第一个字节是高位(排在前面),第二个字节是低位(排在后面)。
b. 对于字节内部的位来说,
-------most significant bits排在前面,是高位,
-------least significant bits排在后面,是低位。
2)在Little Endian的情况下,"排在前面的是低位"
a. 对于顺序的两个字节来说,第一个字节是低位(排在前面),第二个字节是高位(排在后面)。
b. 对于字节内部的位来说,
-------least significant bits排在前面,是低位,
-------most significant bits排在后面,是高位。
这样,在对struct中的成员进行分配的时候,"按排列顺序分配,先分配排在前面的"
1)big endian从高位向低位分配,
a. 对字节,是先分配低地址的字节,再分配高地址的字节。
b. 对位域,先分配most significant bits,再分配least significant bits。
1)little endian从低位向高位分配,
a. 对字节,是先分配低地址的字节,再分配高地址的字节。
b. 对位域,先分配least significant bits,再分配most significant bits。
======================================
以上说的都是分配的顺序。
对于IP协议来说,
1)IP's byte order is big endian.
2)The bit endianness of IP inherits that of the CPU,
3)and the NIC takes care of converting it from/to the bit transmission/reception order on the wire.
并且,按照IP协议,
1)"version" is the most significant four bits of the first byte of an IP header.
2)"ihl" is the least significant four bits of the first byte of the IP header.
也就是说,version必须分配在most significant four bits,
按照上面说的分配顺序,在big endian中,version必须放在前面。
MSB most significant bits
LSB least significant bits
一句话:对于 little-endian 来说 MSB 在高地址,对 big-endian 来说 MSB 在低地址。
Here is how we would write the integer 0x0a0b0c0d for both big endian and little endian systems, according to the rule above:
Write Integer for Big Endian System
byte addr 0 1 2 3
bit offset 01234567 01234567 01234567 01234567
binary 00001010 00001011 00001100 00001101
hex 0a 0b 0c 0d
Write Integer for Little Endian System
byte addr 3 2 1 0
bit offset 76543210 76543210 76543210 76543210
binary 00001010 00001011 00001100 00001101
hex 0a 0b 0c 0d
In both cases above, we can read from left to right and the number is 0x0a0b0c0d.
在小字节序机器上跑测试例1:
- int value = 0x12345678;
- union ValueT
- {
- int value;
- char data[4];
- } a;
- a.value = 0x12345678;
- printf("value is 0x%x\n", a.value);
- printf("address is %p, 0x%x\n",&a.data[0], a.data[0]);
- printf("address is %p, 0x%x\n",&a.data[1], a.data[1]);
- printf("address is %p, 0x%x\n",&a.data[2], a.data[2]);
- printf("address is %p, 0x%x\n",&a.data[3], a.data[3]);
-
-
-
-
-
- struct bitfield{
- int ia:2;
- int ib:6;
- } field;
- field.ia=1;
- field.ib=4;
- char * c;
- c=(char *)&field;
- printf("%d\n",*c);
-
原帖地址:http://www.unixresources.net/linux/clf/program/archive/00/00/64/28/642822.html
亦可参考:http://bbs.chinaunix.net/viewthread.php?tid=823662&extra=&page=1
http://www.unixresources.net/linux/clf/linuxK/archive/00/00/63/86/638637.html
Endianness of CPU
The CPU endianness is the byte and bit order in which it interprets multi-byte integers from on-chip registers, local bus, in-line cache, memory and so on.
Little endian CPUs include Intel and DEC. Big endian CPUs include Motorola 680x0, Sun Sparc and IBM (e.g., PowerPC). MIPs and ARM can be configured either way.
Endianness of Ethernet
Ethernet is big endian. This means the most significant byte of an integer field is placed at a lower wire byte address and transmitted/received in front of the least significant byte.
Endianness of IP
IP's byte order also is big endian. The bit endianness of IP inherits that of the CPU, and the NIC takes care of converting it from/to the bit transmission/reception order on the wire.
分享到:
相关推荐
### 字节序的基础概念 字节序,又称为字节顺序或字节排列方式,指的是在计算机内存中或网络传输过程中多字节数据的存储顺序。简单来说,它定义了多字节数据中各个字节如何按顺序排列。在实际编程工作中,尽管很多...
IP、主机字节序、网络字节序、互转 ------------------------------------------------------- using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Net; using ...
网络字节序和主机字节序 在计算机科学中,字节序(Endianness)是指整数在内存中保存的顺序。不同的 CPU 有不同的字节序类型,这些字节序是指整数在内存中保存的顺序,这个叫做主机序。 常见的有两种字节序:...
《本地字节序和网络字节序:理解与应用》 在计算机科学中,字节序(Byte Order)指的是多字节数据类型在内存中存储时,其各个组成字节的排列顺序。这一概念对于理解数据在网络传输以及跨平台编程中至关重要。本文将...
"字节序与位序详解" 字节序(Byte Order)和位序(Bit Order)是计算机系统中两个重要的概念,它们决定了计算机系统如何存储和处理多字节整数。在本文中,我们将详细介绍字节序和位序的定义、类型、特点以及在...
利用宏将网络字节序和主机字节序ip格式化输出为字符串ip
### 大小端字节序概念与转换 #### 一、引言 在计算机系统中,数据的存储和传输方式至关重要。特别是在网络通信领域,不同的系统可能会采用不同的字节序来存储多字节数据,这可能导致数据解释上的不一致。因此,理解...
字节序分为两种类型:大端字节序(Big-Endian)和小端字节序(Little-Endian)。理解这两种字节序对于进行跨平台的网络通信至关重要,因为不同的处理器架构可能使用不同的字节序。例如,PowerPC和SPARC通常使用大端...
float字节序高低位转换.txt
项目中需要64位数的字节序转换,主机序转换成网路序或者相反转换,写了2个函数,有需要的可以参考。
高字节序,低字节序讲解。高字节序,低字节序讲解。高字节序,低字节序讲解
用C语言写的判断主机字节序的代码,一共有2种方法判断
在跨平台的网络编程中,字节序转换函数如htonl(主机到网络字节序,long)、ntohl(网络到主机字节序,long)、htons(主机到网络字节序,short)和ntohs(网络到主机字节序,short)非常常见,它们确保数据在网络上...
网络字节序与主机字节序
判断主机到底是大端还是小端的c程序!利用位置判断
Java 网络字节序转换是编程过程中一个重要的概念,尤其在跨平台通信和处理二进制数据时。字节序是指多字节数据(如整数或浮点数)在内存或文件中存储的顺序。主要有两种字节序:Big-Endian(大端字节序)和 Little-...
二进制杂谈 1、十进制、二进制、十六进制 2、计算机储存单位 3、进制转换 4、有符号编码 5、反码的设计原理 6、二进制的位运算 7、位操作符 8、内存与内存地址 9、字节序 10、Java解码 11、Java编码
网络字节序是计算机网络通信中的一个重要概念,它涉及到数据在网络中的传输方式。在不同的计算机系统中,数据存储的顺序可能会有所不同,这被称为字节序。主要有两种字节序:大端字节序(Big-Endian)和小端字节序...
网络字节序 主机字节序
在计算机科学中,字节序是一个至关重要的概念,特别是在跨平台通信和网络编程中。字节序,又称端序或尾序,定义了多字节数据如何在内存中存储和在网络上传输。Endianness这一术语源于乔纳森·斯威夫特的《格列佛游记...