socket編程爲何須要htons(), ntohl(), ntohs(),htons() 函數

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

相關文章
相關標籤/搜索