简介
在不同的系统中,当最最基础的数据存在问题的时候,这是最让人头疼的问题。但是,世界就是爱和我们开玩笑,不是么?在芯片中,有两种方式存储数据:
大端
,也叫Big-Endian
,同样有个很感人的名字Motorola
小端
,也叫little-Endian
,同样也有一个和我们息息相关的名字Intel
至于,为什么这么叫,具体的自己去查找。
用在什么场合?
一般小端,会用在数据的存储上,而大端用在数据的传输。前者也叫主机序,后者也叫网络字节序,当然,也不是绝对。至于用什么,当然根据自己的爱好了,当然和协议也有很大的关系。
如何把主机上的数据通过网络传输?
这其中,涉及到很多问题,主机序列是否和网络字节序匹配,这里,分开说明。
主机字节序和网络字节序相同
-
准备工作
//type define uchar(8bit) & uword(16bit) & uint(32) typedef unsigned char uchar; typedef unsigned short uword; typedef unsigned int uint; //Network data buffer #define BUFFER (0x08) //data receved buffer uchar data[BUFFER]; //data uint num;
-
转换代码,如果转换为uint型:
- 接收
Value = *(uint*)&data[0];
- 发送
data[0] = *(uchar*)#
如果存在差异
可以利用如下的宏来进行转换
#define lit_big_TransShort(a_data) (((a_data) & 0x00ff) << 8 | ((a_data) & 0xff00) >> 8)
#define lit_big_TransLong(a_data) (((a_data) & 0xff000000) >> 24 | ((a_data) & 0x000000ff) << 24)
#define lit_big_TransWord(a_data) lit_big_TransShort(a_data)
#define lit_big_TransInt(a_data) (lit_big_TransLong(a_data) | (lit_big_TransShort((a_data) >> 8) << 8))
- 如果有差异,可以经过以下两个步骤:
Value = *(uint*)&data[0];
Value = lit_big_TransInt(Value);
- 或者
num = lit_big_TransInt(num);
data[0] = *(uchar*)#
以上的方式在某些地方存在问题,正如上一篇文章描述的问题:
某些芯片,由于架构的原因,并不支持奇数地址指针的某些数据获取。所以,如果通过这种暴力的指针类型转换是存在问题的,所以,只有提供如下的函数来进行转换。
最好的解决办法,就是自己编写一个类似于网络字节序转主机字节序的函数。
以下是这几个函数:
- htons()
- htonl()
- ntohs()
- ntohl()
记忆规则就是“h/n”表示host or Network,加上to这个向量标识,"s/l"表明转换大小:short/long.