1、大端存储:Big-Endian,低地址存高位字节,高地址存低位字节
2、小端存储:Little-Endian,低地址存低位字节,高地址存高位字节
3、网络字节:存储同大端字节序,网络上传输的数据都是字节流。
4、UDP/TCP/IP协议规定:把接收到的第一个字节当作高位字节看待,这就要求发送端发送的第一个字节是高位字节;而在发送端发送数据时,发送的第一个字节是该数值在内存中的起始地址处对应的那个字节,也就是说,该数值在内存中的起始地址处对应的那个字节就是要发送的第一个高位字节(即:高位字节存放在低地址处),由此可见,多字节数值在发送之前,在内存中因该是以大端法存放的;所以说,网络字节序是大端字节序。
5、常见CPU的字节序:
Big Endian : PowerPC、IBM、Sun
Little Endian : x86、DEC
ARM既可以工作在大端模式,也可以工作在小端模式。
6、网络字节序和主机字节序的转换
ntohs =net to host short int 16位
htons=host to net short int 16位
ntohl =net to host long int 32位
htonl=host to net long int 32位
参考:ntohs, ntohl, htons,htonl的比较和详解 - 月未央 - 博客园
7、判断大小端示例(来源网络)
#include<stdio.h>
int main()
{
//method 1
short int x;
char x0, x1;
x = 0x1122;
x0 = *((char *)&x); //把x的低位地址的值赋给x0;
x1 = *((char *)&x + 1); //把x的高位地址的值赋给x1;
if( x0 == 0x11 && x1 == 0x22)
printf(" This is big-endian \n");
else if( x0 == 0x22 && x1 == 0x11)
printf("This is little-endian \n");
else
printf("bad bad bad \n");
//method 2
int a = 0x1234;
//通过将int强制类型转换成char单字节,通过判断起始存储位置。即等于取b等于a的低地址部分
char b = *(char *)&a;
if( b == 0x12)
{
printf("It is big endina\n");
}else {
printf("It is little endina\n");
}
//method 3 by union
union NUM
{
int c;
char d;//处于低地址
}num;
num.c = 0x1234;
if( num.d == 0x34 )
{
printf("It is also little endina num.d:0x%x\n",num.d);
} else
printf("It is also big endina num.d:0x%x\n",num.d);
return 0;
}
PS:union里的数据都是从同一个地址的低端开始放置,结构体占用的内存大于等于所有成员占用的内存的总和(成员之间可能会存在缝隙),共用体占用的内存等于最长的成员占用的内存。共用体使用了内存覆盖技术,同一时刻只能保存一个成员的值,如果对新的成员赋值,就会把原来成员的值覆盖掉。C语言共用体(C语言union用法)详解
参考:
1、网络通信之 字节序转换原理与网络字节序、大端和小端模式 - GavinJune - 博客园
2、网络通信之 字节序转换原理与网络字节序、大端和小端模式 - 程序员大本营
3、网络传输大端序_大端、小端与网络字节序_秀云南的博客-CSDN博客