注:本文为 “网络字节序” 相关的两篇文章合辑。
两篇前介一样,看应用。第二篇略作重编。
英文引文机翻未校。
大小端及网络字节序
z_ryan 于 2018-01-22 23:58:21 发布
大端模式、小端模式
“大端” 和” 小端” 表示多字节值的哪一端存储在该值的起始地址处:小端存储在起始地址处,即小端字节序;大端存储在起始地址处,即大端字节序;具体的说:
① 大端字节序(Big Endian):最高有效位存于最低内存地址处,最低有效位存于最高内存处;
② 小端字节序(Little Endian):最高有效位存于最高内存地址,最低有效位存于最低内存处。
如下图:当以不同的存储方式,存储数据为 0x12345678 时:
判断字节序
可以通过下面的小程序测试自己的机器是大端字节序还是小端字节序
#include <stdio.h>
union
{
char ch;
int i;
}un;
int main(void)
{
un.i = 0x12345678;
if(un.ch == 0x12)
{
printf("big endian\n");
}
else
{
printf("small endain\n");
}
return 0;
在测试程序中,使用联合体的原因是:union 型数据所占的空间等于其最大的成员所占的空间。对 union 型成员的存取都是相对于该联合体基地址的偏移量为 0 处开始,也就是联合体的访问不论对哪个变量的存取都是从 union 的首地址开始的。通过检测第一个字节存放的数据即可得出结果。
网络字节序
网络上传输的数据都是字节流,对于一个多字节数值,在进行网络传输的时候,先传递哪个字节?也就是说,当接收端收到第一个字节的时候,它将这个字节作为高位字节还是低位字节处理,是一个比较有意义的问题;
UDP/TCP/IP 协议规定:把接收到的第一个字节当作高位字节看待,这就要求发送端发送的第一个字节是高位字节;而在发送端发送数据时,发送的第一个字节是该数值在内存中的起始地址处对应的那个字节。
也就是说,该数值在内存中的起始地址处对应的那个字节就是要发送的第一个高位字节 (即:高位字节存放在低地址处); 由此可见,多字节数值在发送之前,在内存中因该是以大端法存放的;所以说,网络字节序是大端字节序。
在实际中,当在两个存储方式不同的主机上传输时,需要借助字节序转换函数。
字节序转换函数
#include <arpa/inet.h>
//将主机字节序转换为网络字节序
unit32_t htonl (unit32_t hostlong);
unit16_t htons (unit16_t hostshort);
//将网络字节序转换为主机字节序
unit32_t ntohl (unit32_t netlong);
unit16_t ntohs (unit16_t netshort);
说明:h -----host;n----network ;s------short;l----long。
例如:
#include <stdio.h>
#include <arpa/inet.h>
int main()
{
unsigned int x = 0x12345678;
unsigned char *p = (unsigned char *)&x;
printf("%0x_%0x_%0x_%0x\n",p[0],p[1],p[2],p[3]);
unsigned int y = htonl(x);
p = (unsigned char*)&y;
printf("%0x_%0x_%0x_%0x\n",p[0],p[1],p[2],p[3]);
return 0;
}
运行结果:
网络字节序(大端字节序(Big Endian)/ 小端字节序(Little Endian)
JMW1407 于 2020-09-26 08:23:28 发布
1、网络字节序 (Network Byte Order)和本机转换
1、大端、小端字节序
“大端” 和” 小端” 表示多字节值的哪一端存储在该值的起始地址处:小端存储在起始地址处,即小端字节序;大端存储在起始地址处,即大端字节序;具体的说:
① 大端字节序(Big Endian): 最高有效位存于最低内存地址处,最低有效位存于最高内存地址处;
② 小端字节序(Little Endian):最高有效位存于最高内存地址,最低有效位存于最低内存地址处。
“高位数据"和"低位数据”
通常指的是数据在存储或传输时的位置或顺序。
在处理二进制数据、字节序、位操作以及数据存储时非常常见,用于描述数据的物理存储方式或传输顺序。
-
高位数据:指的是数据的高阶位或高字节,通常存储在数据块的起始位置或最高有效位(Most Significant Bit,MSB)。在多字节数据中,高位数据对应于数据的较高位部分。
-
低位数据:指的是数据的低阶位或低字节,通常存储在数据块的末尾或最低有效位(Least Significant Bit,LSB)。在多字节数据中,低位数据对应于数据的较低位部分。
如下图:当以不同的存储方式,存储数据为 0x12345678 时:
视角 1
视角 2
视角 3
网络字节序:大端字节序
网络上传输的数据都是字节流,对于一个多字节数值,在进行网络传输的时候,先传递哪个字节?
也就是说,当接收端收到第一个字节的时候,它将这个字节作为高位字节还是低位字节处理,是一个比较有意义的问题。
UDP/TCP/IP 协议规定:把接收到的第一个字节当作高位字节看待
, 这就要求发送端发送的第一个字节是高位字节;而在发送端发送数据时,发送的第一个字节是该数值在内存中的起始地址处对应的那个字节。换句话说,该数值在内存中的起始地址处对应的那个字节就是要发送的第一个高位字节。
所以,网络字节序就是大端字节序
, 有些系统的本机字节序是小端字节序,有些则是大端字节序,为了保证传送顺序的一致性, 网际协议使用大端字节序来传送数据
。
验证字节序类型
/* 确定你的电脑是大端字节序还是小端字节序 */
#include <stdio.h>
int check1()
{
int i = 1; //1在内存中的表示: 0x00000001
char *pi = (char *)&i; //将int型的地址强制转换为char型
return *pi == 0