簡介
在不同的系統中,當最最基礎的數據存在問題的時候,這是最讓人頭疼的問題。但是,世界就是愛和我們開玩笑,不是么?在芯片中,有兩種方式存儲數據:
大端
,也叫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.