5、【Linux網絡編程】socket中htonl() htons() ntohl() ntohs()及inet_ntoa() inet_addr()的用法


htonl() htons() ntohl() ntohs()及inet_ntoa() inet_addr()的用法

一、網絡字節序和主機字節序

注:其中的h表示“host”,n表示“net”,l表示“long”,s表示“short”,a表示“ascii”,addr表示“in_addr結構體”

這些函數都與網絡字節序和主機字節序列的轉換,首先介紹一下網絡字節序和主機字節序列及兩者之間的轉換關系。

網絡字節順序NBO(Network Byte Order):
      按從高到低的順序存儲,在網絡上使用統一的網絡字節順序,可以避免兼容性問題。

主機字節順序(HBO,Host Byte Order):
      不同的機器HBO不相同,與CPU設計有關,數據的順序是由cpu決定的,而與操作系統無關。 
      如 Intel x86結構下,short型數0x1234表示為34 12, int型數0x12345678表示為78 56 34 12 。
      如IBM   power PC結構下,short型數0x1234表示為12   34, int型數0x12345678表示為12 34 56 78

以IP地址127.0.0.1為例,看看兩者之間是如何轉換的:

1 第一步   127   .   0    .   0    .   1                 把IP地址每一部分轉換為8位的二進制數。
2 第二步 01111111.00000000.00000000.00000001 = 2130706433 (主機字節序)
3 然后把上面的四部分二進制數從右往左按部分重新排列,那就變為:
4 第三步 00000001.00000000.00000000.01111111 = 16777343 (網絡字節序)

【示例】

1 SOCKADDR_IN addrSrv;
2 addrSrv.sin_addr.S_un.S_addr=htonl(2130706433);
3 addrSrv.sin_family=AF_INET;
4 addrSrv.sin_port=htons(6000);

  先是定義了一個IP地址結構體addrSrv,然后初始化它的IP時addrSrv.sin_addr.S_un.S_addr必須是賦值IP地址的網絡字節序,htonl函數的作用是把一個主機字節序轉換為網絡字節序,也就是上面轉換過程中第二步轉換為第三步的作用,127.0.0.1的主機字節序是2130706433,把主機字節序2130706433轉換為網絡字節序就是htonl(2130706433)=16777343,所以如果你知道網絡字節序是16777343的話,addrSrv.sin_addr.S_un.S_addr=htonl(2130706433);與addrSrv.sin_addr.S_un.S_addr=16777343;是完全一樣的。

1 addrSrv.sin_addr.S_un.S_addr=htonl(2130706433);//這句還可以寫為下面的樣子
2 addrSrv.sin_addr.S_un.S_addr=inet_addr("127.0.0.1"); 
3 //結果是完全一樣的。
4 //可見inet_addr函數的轉換作用就是上面的第一步到第三步的轉換。

下面再看端口的主機字節序與網絡字節序的轉換。以6000端口為例。

1 第一步     00010111         01110000            =           6000 (主機字節序)
2 //端口號其實就已經是主機字節序了,首先要把端口號寫為16位的二進制數,分前8位和后8位。
3 第二步      01110000          00010111          =            28695 (網絡字節序)
4 //然后把主機字節序的前八位與后八位調換位置組成新的16位二進制數,這新的16位二進制數就是網絡字節序的二進制表示了。

  因此,如果你知道6000端口的網絡字節序是28695的話。 addrSrv.sin_port=htons(6000);可以直接寫為 addrSrv.sin_port=28695;結果是一樣的,htons的作用就是把端口號主機字節序轉換為網絡字節序。

二、htonl() htons() ntohl() ntohs()及inet_ntoa() inet_addr()的用法

htonl()函數:將主機字節序轉換為網絡字節序

  函數原型:

1 u_long PASCAL FAR htonl (u_long hostlong);

htons()函數:將主機字節序轉換為網絡字節序

  函數原型:

1 u_short PASCAL FAR htons (u_short hostshort);

ntohl()函數:網絡順序轉換成主機順序

  函數原型:

1 u_long PASCAL FAR ntohl (u_long netlong);

ntohs()函數:網絡順序轉換成主機順序

  函數原型:

1 u_short PASCAL FAR ntohs (u_short netshort);

inet_ntoa()函數:接受一個in_addr結構體類型的參數並返回一個以點分十進制格式表示的IP地址字符串。

  函數原型:

1 char FAR * PASCAL FAR inet_ntoa (struct in_addr in);

inet_addr()函數:需要一個字符串作為其參數,該字符串指定了以點分十進制格式表示的IP地址(例如:192.168.0.16)。

          而且inet_addr函數會返回一個適合分配給S_addr的u_long類型的數值。

  函數原型:

1 unsigned long PASCAL FAR inet_addr (const char FAR * cp);

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM