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