0
点赞
收藏
分享

微信扫一扫

两种大小端判断的方式

网络通信是按照字节流进行数据交换的,主机根据不同的CPU型号可能是大段存储,也可能是小端存储。而网络字节序在TCP/IP协议中已经规定好了,采用大端的排序方式。
所以网络通信中一般将需要传输的整数型值转换成网络字节序。
从本机字节序转换成网络字节序:host to net short/long

#include <arpa/inet.h>
uint32_t htonl(uint32_t hostlong);
uint16_t htons(uint16_t hostshort);

从网络字节序转换成本机字节序

#include <arpa/inet.h>
uint32_t ntohl(uint32_t netlong);
uint16_t ntohs(uint16_t netlshort);

转换的原理其实也很简单,就是判断一下本地是大端还是小端,是大端就转换一下序列,否则啥都不干。
下面介绍两种用来判断大小端的方法:

第一种,使用union

大端是指低字节存储在高地址;小端存储是指低字节存储在低地址。我们可以根据联合体来判断该系统是大端还是小端。因为联合体变量总是从低地址存储。

bool isNetByteOrder()
{
union test {
int i;
char c;
};
test t;
t.i = 1;
// 如果是大端,则 t.c 为0x00,则 t.c != 1 返回true
// 否则返回false
return (t.c != 1);
}

第二种,使用char指针

随意找一个2字节的十六进制数值,如0x1234
如果本地是小端编码,那么12存在高地址,34存在低地址。那么强行把0x1234转换成1字节的char时,高字节会被丢弃,留下低字节值34。
如果本地是大端编码,那么高地址字节种存储的是34,12存在低地址,强制转换成1字节的char时,高字节会被丢弃,留下低字节值12。

bool isNetByteOrder()
{
unsigned short mode = 0x1234;
char* pmode = (char*) &mode;
// 如果将低字节放在低位,则是小端字节序
return (*pmode != 0x34);
}

实现htons函数

uint16_t htons(uint16_t hostshort)
{
if (isNetByteOrder())
return hostshort;
else
return ((uint16_t)(hostshort >> 8)) | ((uint16_t)((hostshort & 0x00ff) << 8));
}


举报

相关推荐

0 条评论