大端字节序(big-endian):最大字节地址出现在最低有效字节上(LSB,Least Significant Byte)。
小端字节序(little-endian):最大字节地址出现在最高有效字节上(MSB, Most Significant Byte)。
不管大端还是小端,单个字节顺序是相同;
网络协议指定了字节序,TCP/IP协议使用了大端字节序(一般称为网络序)。本地主机的字节序称为(主机序)。
代码:
#include <stdio.h>
#include <stdlib.h>
#include <arpa/inet.h>
int main(int argc, const char * argv[])
{
int a = 0x15253545;
char *p = (char*)&a;
if (0x45 == *p)
{
printf("little-endian.\n");
}
else
{
printf("big-endian.\n");
}
for (int i = 0; i < sizeof(int); ++i)
{
printf("%#x\n", *(p + i));
}
int b = htonl(a);
printf("%#x --> %#x.\n", a, b);
printf("%d -- > %d.\n", 5, htonl(5));
return 0;
}
# Mac OS Big Sur 11.1
# 2 GHz 四核Intel Core i5
# Xcode
little-endian.
0x45
0x35
0x25
0x15
0x15253545 --> 0x45352515.
5 -- > 83886080.
Program ended with exit code: 0
// htonl的实现
#define __DARWIN_OSSwapConstInt32(x) \
((__uint32_t)((((__uint32_t)(x) & 0xff000000U) >> 24) | \
(((__uint32_t)(x) & 0x00ff0000U) >> 8) | \
(((__uint32_t)(x) & 0x0000ff00U) << 8) | \
(((__uint32_t)(x) & 0x000000ffU) << 24)))
应用场景:
SOCKET:发送消息:主机序转换成网络序;接收消息:将网络序转换成主机序;
判断设备的字节序:主要通过某个类型的变量第一个字节是否是预期的数据,包括当前测试代码是使用0x15253545的32位数字。所谓的使用UNION也是这个道理。