什么是字節(jié)序
采用維基百科的解釋如下:
在幾乎所有的機(jī)器上,多字節(jié)對(duì)象都被存儲(chǔ)為連續(xù)的字節(jié)序列。例如在C語(yǔ)言中,一個(gè)類型為int的變量x地址為0x100,那么其對(duì)應(yīng)地址表達(dá)式&x的值為0x100。且x的四個(gè)字節(jié)將被存儲(chǔ)在存儲(chǔ)器的0x100, 0x101, 0x102, 0x103位置。
而存儲(chǔ)地址內(nèi)的排列則有兩個(gè)通用規(guī)則。一個(gè)多位的整數(shù)將按照其存儲(chǔ)地址的最低或最高字節(jié)排列。如果最低有效字節(jié)在最高有效字節(jié)的前面,則稱小端序;反之則稱大端序。在網(wǎng)絡(luò)應(yīng)用中,字節(jié)序是一個(gè)必須被考慮的因素,因?yàn)椴煌瑱C(jī)器類型可能采用不同標(biāo)準(zhǔn)的字節(jié)序,所以均按照網(wǎng)絡(luò)標(biāo)準(zhǔn)轉(zhuǎn)化。
例如假設(shè)上述變量x類型為int,位于地址0x100處,它的十六進(jìn)制為0x01234567,地址范圍為0x100~0x103字節(jié),其內(nèi)部排列順序依賴于機(jī)器的類型。大端法從首位開始將是:0x100: 01, 0x101: 23,..。而小端法將是:0x100: 67, 0x101: 45,..


網(wǎng)絡(luò)字節(jié)序
談網(wǎng)絡(luò)字節(jié)序(Endianness)之前我們先說(shuō)說(shuō)什么是字節(jié)序。字節(jié)序又叫端序,就是指計(jì)算機(jī)中存放 多字節(jié)數(shù)據(jù)的字節(jié)的順序。典型的就是數(shù)據(jù)存放在內(nèi)存中或者網(wǎng)絡(luò)傳輸時(shí)的字節(jié)的順序。常用的字節(jié)序有大端序(big-endian),小端序(litle-endian,另還有不常見的混合序middle-endian)。不同的CPU可能會(huì)使用不同的字節(jié)序,如X86,PDP-11等處理器為小端序,Motorola 6800,PowerPC 970等使用的是大端序。小端序是指低字節(jié)位存放在內(nèi)存地址的低端,高端序是指高位字節(jié)存放在內(nèi)存的低端。 舉個(gè)例子來(lái)說(shuō)明什么是大端序和小端序: 比如一個(gè)4字節(jié)的整數(shù) 16進(jìn)制形式為 0x12345678,最左邊是高位。
大端序
低位 > > > > 高位
12 34 56 78
小端序
低位 > > > > 高位
78 56 34 12
TCP/IP 各層協(xié)議將字節(jié)序使用的是大端序,我們把TCP/IP協(xié)議中使用的字節(jié)序稱之為網(wǎng)絡(luò)字節(jié)序。 編程的時(shí)候可以使用定義在sys/_endian.h中的相關(guān)的接口進(jìn)行本地字節(jié)序和網(wǎng)絡(luò)字節(jié)序的互轉(zhuǎn)。
iOS開發(fā)中應(yīng)用
方法一(宏定義):
#define ntohs(x) __DARWIN_OSSwapInt16(x) // 16位整數(shù) 網(wǎng)絡(luò)字節(jié)序轉(zhuǎn)主機(jī)字節(jié)序
#define htons(x) __DARWIN_OSSwapInt16(x) // 16位整數(shù) 主機(jī)字節(jié)序轉(zhuǎn)網(wǎng)絡(luò)字節(jié)序
#define ntohl(x) __DARWIN_OSSwapInt32(x) //32位整數(shù) 網(wǎng)絡(luò)字節(jié)序轉(zhuǎn)主機(jī)字節(jié)序
#define htonl(x) __DARWIN_OSSwapInt32(x) //32位整數(shù) 主機(jī)字節(jié)序轉(zhuǎn)網(wǎng)絡(luò)字節(jié)序
以上聲明中 n代表netwrok, h代表host ,s代表short,l代表long
如果數(shù)據(jù)是單字節(jié)的話,則其沒(méi)有字節(jié)序的說(shuō)法了。
方法二(直接轉(zhuǎn)換):
// Convert result to 4 byte big-endian (network byte order)
// and then convert to raw data.
UInt32 result = OSSwapHostToBigInt32((uint32_t)resultHostNum);
return [NSData dataWithBytes:&result length:4];