https://blog.csdn.net/myyllove/article/details/83380209編程
在C/C++寫網絡程序的時候,每每會遇到字節的網絡順序和主機順序的問題。這是就可能用到htons(), ntohl(), ntohs(),htons()這4個函數。網絡
網絡字節順序與本地字節順序之間的轉換函數:函數
htonl()--"Host to Network Long" 把unsigned long類型從主機序轉換到網絡序 ntohl()--"Network to Host Long" 把unsigned long類型從網絡序轉換到主機序 htons()--"Host to Network Short" 把unsigned short類型從主機序轉換到網絡序 ntohs()--"Network to Host Short" 把unsigned short類型從網絡序轉換到主機序
在使用little endian的系統中 這些函數會把字節序進行轉換
在使用big endian類型的系統中 這些函數會定義成空宏
一樣 在網絡程序開發時 或是跨平臺開發時 也應該注意保證只用一種字節序 否則兩方的解釋不同就會產生bug.
注:、網絡與主機字節轉換函數:htons ntohs htonl ntohl (s 就是short l是long h是host n是network)
之因此須要這些函數是由於計算機數據表示存在兩種字節順序:NBO與HBOspa
網絡字節順序NBO(Network Byte Order):
按從高到低的順序存儲,在網絡上使用統一的網絡字節順序,能夠避免兼容性問題。操作系統
主機字節順序(HBO,Host Byte Order):
不一樣的機器HBO不相同,與CPU設計有關,數據的順序是由cpu決定的,而與操做系統無關。.net
如 Intelx86結構下,short型數0x1234表示爲34 12, int型數0x12345678表示爲78 56 34 12設計
如IBM power PC結構下,short型數0x1234表示爲12 34, int型數0x12345678表示爲12 34 56 78
因爲這個緣由不一樣體系結構的機器之間沒法通訊,因此要轉換成一種約定的數序,也就是網絡字節順序,其實就是如同powerpc那樣的順序 。在PC開發中有ntohl和htonl函數能夠用來進行網絡字節和主機字節的轉換。 blog
2.排序
在Linux和Windows網絡編程時須要用到htons和htonl函數,用來將主機字節順序轉換爲網絡字節順序。內存
在Intel機器下,執行如下程序
int main() { printf("%d \n",htons(16)); return 0; }
獲得的結果是4096,初一看感受很怪。
解釋以下,數字16的16進製表示爲0x0010,數字4096的16進製表示爲0x1000。 因爲Intel機器是小尾端,存儲數字16時實際順序爲1000,存儲4096時實際順序爲0010。所以在發送網絡包時爲了報文中數據爲0010,須要 通過htons進行字節轉換。若是用IBM等大尾端機器,則沒有這種字節順序轉換,但爲了程序的可移植性,也最好用這個函數。
另外用注意,數字所佔位數小於或等於一個字節(8 bits)時,不要用htons轉換。這是由於對於主機來講,大小尾端的最小單位爲字節(byte)。
包含的頭文件爲:"winsock2.h"
https://blog.csdn.net/smilelance/article/details/3091744
不一樣的CPU有不一樣的字節序類型 這些字節序是指整數在內存中保存的順序 這個叫作主機序
最多見的有兩種
Little endian | 將低序字節存儲在起始地址 | 最符合人的思惟的字節序 地址低位存儲值的低位 地址高位存儲值的高位 怎麼講是最符合人的思惟的字節序,是由於從人的第一觀感來講 低位值小,就應該放在內存地址小的地方,也即內存地址低位 反之,高位值就應該放在內存地址大的地方,也即內存地址高位 |
Big endian | 將高序字節存儲在起始地址 | 最直觀的字節序 地址低位存儲值的高位 地址高位存儲值的低位 爲何說直觀,不要考慮對應關係 只須要把內存地址從左到右按照由低到高的順序寫出 把值按照一般的高位到低位的順序寫出 二者對照,一個字節一個字節的填充進去 |
例子:在內存中雙字0x01020304(DWORD)的存儲方式
內存地址 | 4000 | 4001 | 4002 | 4003 |
LE | 04 | 03 | 02 | 01 |
BE | 01 | 02 | 03 | 04 |
x86系列CPU都是little-endian的字節序. 網絡字節順序是TCP/IP中規定好的一種數據表示格式,它與具體的CPU類型、操做系統等無關,從而能夠保證數據在不一樣主機之間傳輸時可以被正確解釋。網絡字節順序採用big endian排序方式。不一樣的CPU上運行不一樣的操做系統,字節序也是不一樣的,參見下表。處理器 操做系統 字節排序Alpha 所有 Little endianHP-PA NT Little endianHP-PA UNIX Big endianIntelx86 所有 Little endian <-----x86系統是小端字節序系統Motorola680x() 所有 Big endianMIPS NT Little endianMIPS UNIX Big endianPowerPC NT Little endianPowerPC 非NT Big endian <-----PPC系統是大端字節序系統RS/6000 UNIX Big endianSPARC UNIX Big endianIXP1200 ARM核心 所有 Little endian