什么是字節(jié)序
采用維基百科的解釋如下:
在幾乎所有的機器上镣衡,多字節(jié)對象都被存儲為連續(xù)的字節(jié)序列生蚁。例如在C語言中崩哩,一個類型為int的變量x地址為0x100巡球,那么其對應(yīng)地址表達式&x的值為0x100。且x的四個字節(jié)將被存儲在存儲器的0x100, 0x101, 0x102, 0x103位置邓嘹。
而存儲地址內(nèi)的排列則有兩個通用規(guī)則酣栈。一個多位的整數(shù)將按照其存儲地址的最低或最高字節(jié)排列。如果最低有效字節(jié)在最高有效字節(jié)的前面汹押,則稱小端序矿筝;反之則稱大端序。在網(wǎng)絡(luò)應(yīng)用中棚贾,字節(jié)序是一個必須被考慮的因素窖维,因為不同機器類型可能采用不同標(biāo)準的字節(jié)序,所以均按照網(wǎng)絡(luò)標(biāo)準轉(zhuǎn)化妙痹。
例如假設(shè)上述變量x類型為int铸史,位于地址0x100處,它的十六進制為0x01234567怯伊,地址范圍為0x100~0x103字節(jié)琳轿,其內(nèi)部排列順序依賴于機器的類型。大端法從首位開始將是:0x100: 01, 0x101: 23,..耿芹。而小端法將是:0x100: 67, 0x101: 45,..
網(wǎng)絡(luò)字節(jié)序
談網(wǎng)絡(luò)字節(jié)序(Endianness)之前我們先說說什么是字節(jié)序崭篡。字節(jié)序又叫端序,就是指計算機中存放 多字節(jié)數(shù)據(jù)的字節(jié)的順序吧秕。典型的就是數(shù)據(jù)存放在內(nèi)存中或者網(wǎng)絡(luò)傳輸時的字節(jié)的順序琉闪。常用的字節(jié)序有大端序(big-endian),小端序(litle-endian,另還有不常見的混合序middle-endian)砸彬。不同的CPU可能會使用不同的字節(jié)序塘偎,如X86疗涉,PDP-11等處理器為小端序,Motorola 6800,PowerPC 970等使用的是大端序吟秩。小端序是指低字節(jié)位存放在內(nèi)存地址的低端咱扣,高端序是指高位字節(jié)存放在內(nèi)存的低端。 舉個例子來說明什么是大端序和小端序: 比如一個4字節(jié)的整數(shù) 16進制形式為 0x12345678涵防,最左邊是高位闹伪。
大端序
低位 > > > > 高位
12 34 56 78
小端序
低位 > > > > 高位
78 56 34 12
TCP/IP 各層協(xié)議將字節(jié)序使用的是大端序,我們把TCP/IP協(xié)議中使用的字節(jié)序稱之為網(wǎng)絡(luò)字節(jié)序壮池。 編程的時候可以使用定義在sys/_endian.h中的相關(guā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)主機字節(jié)序
#define htons(x) __DARWIN_OSSwapInt16(x) // 16位整數(shù) 主機字節(jié)序轉(zhuǎn)網(wǎng)絡(luò)字節(jié)序
#define ntohl(x) __DARWIN_OSSwapInt32(x) //32位整數(shù) 網(wǎng)絡(luò)字節(jié)序轉(zhuǎn)主機字節(jié)序
#define htonl(x) __DARWIN_OSSwapInt32(x) //32位整數(shù) 主機字節(jié)序轉(zhuǎn)網(wǎng)絡(luò)字節(jié)序
以上聲明中 n代表netwrok, h代表host 椰憋,s代表short厅克,l代表long
如果數(shù)據(jù)是單字節(jié)的話,則其沒有字節(jié)序的說法了橙依。
方法二(直接轉(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];