大小字节序
這是我的博客真正內容的第一篇,就從最近工作上遇到的一個問題開始吧——大小端字節序
首先我先從簡單的概念開始介紹大小端字節序吧:
概念:
字節序是指多字節數據在計算機內存中存儲或者網絡傳輸時各字節序的存儲順序(我從網上找到的,個人認為這句表達的已經很明確了)
下面是常見的字節序:
1、Little endian(小端字節序LE):就是低位放在低地址,高位放在高地址;
2、Big endian(大端字節序BE):就是低位放在高地址,高位放在低地址;
eg:將0x12345678寫到以0x0000開始的內存中,有以下結論:
地址??????????? LE??????????? BE
0x0000???????0x78????????0x12
0x0001?????? 0x56????????0x34
0x0002?????? 0x34??????? 0x56
0x0003?????? 0x12??????? 0x78
以上就是最基本的知識點了,下面介紹做項目需要的一些基礎知識吧:
網絡字節序:
網絡字節序是TCP/IP中規定的一種數據表示格式,這與操作系統、CPU等無關,這里我們應該察覺到,既然與操作系統以及硬件無關的話,說明在TCP/IP的協議之下,信息的傳輸是不需要做大寫端字節序的轉換的,我想這也是TCP/IP協議的一個強大之處,還有一點就是網絡字節順序都是采用BE,也就是上面我們所介紹的大端字節序
既然有了這幾種字節序,那么我們可以想象,當兩臺不同字節序的主機之間進行通信的話,如果我們不采取一定的措施,比如說上面的例子中,就會被解釋為不同的數據,這就會造成數據的錯亂,這樣的話,你要做的項目自然會是以失敗告終,那么如何處理類似這種事件呢?下面我來介紹一下大小端字節序、以及大小端字節序與網絡字節序是如何進行轉換的:
其實很簡單比如說在一個系統中一個數被理解為A-B-C-D(A/B/C/D各占8位),我們只要把它變為D-C-B-A即可。下面是一個宏塊的操作:
#define ChangeEndian(in) ( ( (in >> 24) & 0xff) | (?(in >> 8) & 0xff00) | ( (in << 8) & 0xff0000) | (in << 24))/*4字節*/
#define ChangeEndian(in) ( ( (in >> 8) & 0xff) | (in << 8))/*2字節*/
上面兩個語句,就是實現大小端字節序的轉換,具體的理解,大家可以按照實現的方法來一遍,其實也挺簡單的;好了下面我將介紹幾個函數(bsd socket提供的轉換函數),這幾個函數在網絡通信時有存在的必要
1、htons()把unsigned short類型從主機序轉換到網絡序
2、htonl()把unsigned long類型從主機序轉換到網絡序
3、ntohs()把unsigned short類型從網絡序轉換到主機序
4、ntohl()把unsigned long類型從網絡序轉換到主機序
由于網絡字節序都是BE,所以在BE類型的系統中,這些函數定義成空宏。
在做到網絡開發或者是跨平臺項目時,需要注意字節序的問題。
下面是我自己寫的一個簡單的測試系統的字節序的程序
#include <stdio.h>
#define ChangeEndian(in) ( ( (in >> 24) & 0xff) | (?(in >> 8) & 0xff00) | ( (in << 8) & 0xff0000) | (in << 24))/*4字節*/
int main(int argc, char** argv)
{
int i_num = 0x12345678;
int j_num = 0x12;
printf("[0]:0x%x\n", *((char*)&i_num + 0) );
printf("[1]:0x%x\n", *((char*)&i_num + 1) );
printf("[2]:0x%x\n", *((char*)&i_num + 2) );
printf("[3]:0x%x\n", *((char*)&i_num + 3) );
if(j_num == *((char*)&i_num + 3))
{
printf("The endian of this System is LE\n");
}
else
{
printf("The endian of this System is BE\n");
}
return 1;
}
?對于枚舉類型的數據進行轉換時需要強制轉換一下,再賦值給原變量
轉載于:https://www.cnblogs.com/jpf-blog/archive/2013/03/25/2980729.html
總結
- 上一篇: Annotation之补充
- 下一篇: JadePool应用范例:创建China