ntohs, ntohl, htons,htonl inet_aton等詳解

ntohs =net to host short int 16位
htons=host to net short int 16位
ntohs =net to host long int 32位
htonl=host to net 

  long int   32位
簡述:
     將一個無符號短整形數從網絡字節順序轉換爲主機字節順序。
     #include
     u_short PASCAL FAR ntohs( u_short netshort);
     netshort:一個以網絡字節順序表達的16位數。
註釋:
     本函數將一個16位數由網絡字節順序轉換爲主機字節順序。
返回值:
     ntohs()返回一個以主機字節順序表達的數。

將主機的無符號短整形數轉換成網絡字節順序。
#include
u_short PASCAL FAR htons( u_short hostshort);
hostshort:主機字節順序表達的16位數。
註釋:
本函數將一個16位數從主機字節順序轉換成網絡字節順序。
返回值:
htons()返回一個網絡字節順序的值。

這2個函數提供了主機字節順序與網絡字節順序的轉換

比如網絡字節 爲 00 01
u_short     a;如何直接對應的話     a=0100; 爲什麼呢?因爲主機是從高字節到低字節的,所以應該轉化後
a=ntohs(0001); 這樣 a=0001;

首先,假設你已經有了一個sockaddr_in結構體ina,你有一個IP地址"132.241.5.10" 要儲存在其中,你就要用到函數inet_addr(),將IP地址從 點數格式轉換成無符號長整型。使用方法如下:
ina.sin_addr.s_addr = inet_addr("132.241.5.10");
; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 160%; ">注意,inet_addr()返回的地址已經是網絡字節格式,所以你無需再調用函數htonl()。
我們現在發現上面的代碼片斷不是十分完整的,因爲它沒有錯誤檢查。顯而易見,當inet_addr()發生錯誤時返回-1。記住這些二進制數字?(無符號數)-1僅僅和IP地址255.255.255.255相符合!這可是廣播地址!大錯特 錯!記住要先進行錯誤檢查。
好了,現在你可以將IP地址轉換成長整型了。有沒有其相反的方法呢?它可以將一個in_addr結構體輸出成點數格式?這樣的話,你就要用到函數 inet_ntoa()("ntoa"的含義是"network to ascii"),就像這樣:
printf("%s",inet_ntoa(ina.sin_addr));
它將輸出IP地址。需要注意的是inet_ntoa()將結構體in-addr作爲一個參數,不是長整形。同樣需要注意的是它返回的是一個指向一個字符的指針。它是一個由inet_ntoa()控制的靜態的固定的指針,所以每次調用 inet_ntoa(),它就將覆蓋上次調用時所得的IP地址。例如:
char *a1, *a2;
.
.
a1 = inet_ntoa(ina1.sin_addr);
a2 = inet_ntoa(ina2.sin_addr);
printf("address 1: %s ",a1);
printf("address 2: %s ",a2);
輸出如下:
address 1: 132.241.5.10
address 2: 132.241.5.10
假如你需要保存這個IP地址,使用strcopy()函數來指向你自己的字符指針。
***********************************************************************************************************************************
htonl()表示將32位的主機字節順序轉化爲32位的網絡字節順序 htons()表示將16位的主機字節順序轉化爲16位的網絡字節順序(ip地址是32位的端口號是16位的 )
inet_ntoa()
簡述:
     將網絡地址轉換成“.”點隔的字符串格式。
     #include
     char FAR* PASCAL FAR inet_ntoa( struct in_addr in);
     in:一個表示Internet主機地址的結構。
註釋:
     本函數將一個用in參數所表示的Internet地址結構轉換成以“.” 間隔的諸如“a.b.c.d”的字符串形式。請注意inet_ntoa()返回的字符串存放在WINDOWS套接口實現所分配的內存中。應用程序不應假設該內存是如何分配的。在同一個線程的下一個WINDOWS套接口調用前,數據將保證是有效。
返回值:
     若無錯誤發生,inet_ntoa()返回一個字符指針。否則的話,返回NVLL。其中的數據應在下一個WINDOWS套接口調用前複製出來。
參見:
     inet_addr().

測試代碼如下
include
#include
#include
#include
p: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; line-height: 160%; ">int main(int aargc, char* argv[])
{
         struct in_addr addr1,addr2;
         ulong   l1,l2;
         l1= inet_addr("192.168.0.74");
         l2 = inet_addr("211.100.21.179");
         memcpy(&addr1, &l1, 4);
         memcpy(&addr2, &l2, 4);
         printf("%s : %s ", inet_ntoa(addr1), inet_ntoa(addr2));     //注意這一句的運行結果
         printf("%s ", inet_ntoa(addr1));
         printf("%s ", inet_ntoa(addr2));
         return 0;
}
實際運行結果如下:
192.168.0.74 : 192.168.0.74       //從這裏可以看出,printf裏的inet_ntoa只運行了一次。
192.168.0.74
211.100.21.179
inet_ntoa返回一個char *,而這個char *的空間是在inet_ntoa裏面靜態分配的,所以inet_ntoa後面的調用會覆蓋上一次的調用。第一句printf的結果只能說明在printf裏面的可變參數的求值是從右到左的,僅此而已。

inet_aton,inet_addr和inet_ntoa在點分十進制數串(如,“192.168.1.10")與他的32位網絡字節二進制值之前轉換IPV4地址,有2個比較新的函數inet_pton和inet_ntop,這2個對IPV4和IPV6地址都能處理
       #include <sys/socket.h>
       #include <netinet/in.h>
       #include <arpa/inet.h>

       int inet_aton(const char *cp, struct in_addr *inp);

       in_addr_t inet_addr(const char *cp);

       char *inet_ntoa(struct in_addr in);

inet_aton() converts the Internet host address cp from the standard
       numbers-and-dots notation into binary data and stores it in the struc‐
       ture that inp points to. inet_aton() returns non-zero if the address is
       valid, zero if not.

inet_aton() 轉換網絡主機地址cp爲二進制數值,並存儲在struct in_addr結構中,即第二個參數*inp,函數返回非0表示cp主機有地有效,返回0表示主機地址無效。

The inet_addr() function converts the Internet host address cp from
       numbers-and-dots notation into binary data in network byte order.   If
       the input is invalid, INADDR_NONE (usually -1) is returned. This is an
       obsolete interface to inet_aton(), described immediately above; it is
       obsolete   because   -1 is a valid address (255.255.255.255), and
       inet_aton() provides a cleaner way to indicate error return.
inet_addr函數轉換網絡主機地址(如192.168.1.10)爲網絡字節序二進制值,如果參數char *cp無效,函數返回-1(INADDR_NONE),這個函數在處理地址爲255.255.255.255時也返回- 1,255.255.255.255是一個有效的地址,不過inet_addr無法處理;

The inet_ntoa() function converts the Internet host address in given in
       network byte order to a string in standard numbers-and-dots notation.
       The string is returned in a statically allocated buffer, which subse‐
       quent calls will overwrite.
inet_ntoa 函數轉換網絡字節排序的地址爲標準的ASCII以點分開的地址,,該函數返回指向點分開的字符串地址的指針,該字符串的空間爲靜態分配的,這意味着在第二次調用該函數時,上一次調用將會被重寫(覆蓋),所以如果需要保存該串最後複製出來自己管理!


現在一般使用inet_aton和inet_ntoa來處理網絡字節和主機字節之間的轉換;

有兩個更新的函數inet_pton和inet_ntop這2個函數能夠處理ipv4和ipv6,原型如下
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
int inet_pton(int af, const char *src, void *dst);

這個函數轉換字符串到網絡地址,第一個參數af是地址族,轉換後存在dst中
inet_pton 是inet_addr的擴展,支持的多地址族有下列:

AF_INET
       src爲指向字符型的地址,即ASCII的地址的首地址(ddd.ddd.ddd.ddd格式的),函數將該地址
       轉換爲in_addr的結構體,並複製在*dst中

AF_INET6
      
src爲指向IPV6的地址,,函數將該地址
       轉換爲in6_addr的結構體,並複製在*dst中

如果函數出錯將返回一個負值,並將errno設置爲EAFNOSUPPORT,如果參數af指定的地址族和src格式不對,函數將返回0。

函數inet_ntop進行相反的轉換原型如下
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
const char *inet_ntop(int af, const void *src, char *dst, socklen_t cnt);
這個函數轉換網絡二進制結構到ASCII類型的地址,參數的作用和上面相同,只是多了一個參數socklen_t cnt,他是所指向緩存區dst的大小,避免溢出,如果緩存區太小無法存儲地址的值,則返回一個空指針,並將errno置爲ENOSPC
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章