inet_aton和inet_network和inet_addr三者比較-《別怕Linux編程》之五


http://roclinux.cn/?p=1160

知識背景:

210.25.132.181屬於IP地址的ASCII表示法,也就是字符串形式。英語叫做IPv4 numbers-and-dots notation。

如果把210.25.132.181轉換為整數形式,是3524887733,這個就是整數形式的IP地址。英語叫做binary data。(其實binary是二進制的意思)

問題所在:

如何在字符串形式的IP和整數形式的IP之間轉換呢?

問題解決思路:

有三個函數可以解決這個問題,當然不止這三個函數,只是這三個函數最常用且最易混淆。

隆重推出他們:inet_network(), inet_addr(), inet_aton()!!

三者定義:

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

in_addr_t inet_addr(const char *cp);

in_addr_t inet_network(const char *cp);

三者區別:

先說出區別吧,不賣關子。但其實這樣不好,因為我怕你因為知道了結論而不去動手實踐了。(你不會的,是吧? ^_^)

紙上得來終覺淺,絕知此事要躬行。

inet_addr和inet_network函數都是用於將字符串形式轉換為整數形式用的,兩者區別很小,inet_addr返回的整數形式是網絡字節序,而inet_network返回的整數形式是主機字節序。(你一定會納悶,為什么函數叫inet_network,卻返回的是主機字節序,呵呵,就是這么奇怪,你又有什么辦法呢…)其他地方兩者並無二異。他倆都有一個小缺陷,那就是當IP是255.255.255.255時,這兩個“小子”(對這兩個函數的昵稱,請諒解…^_^)會認為這是個無效的IP地址,這是歷史遺留問題,其實在目前大部分的路由器上,這個255.255.255.255的IP都是有效的。

inet_aton函數和上面這倆小子的區別就是在於他認為255.255.255.255是有效的,他不會冤枉這個看似特殊的IP地址。所以我們建議你多多支持這個函數,那兩個小子還是少用為好:)對了,inet_aton函數返回的是網絡字節序的IP地址。

好了,區別就這么簡單,只要你能潛下心來看五分鍾,就OK了。哦,忘了,什么叫網絡字節序,什么叫主機字節序?這兩個概念,如果你不太了解,你最好去找一本socket編程的書籍看一看,我保證沒有5分鍾,你就會了解這兩個概念。

編程舉例:

#include<unistd.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<netinet/in.h>
#include<sys/socket.h>
#include<sys/types.h>
 
int main()
{
        char str[]="255.255.255.255";
        in_addr_t r1,r2,r3;
        struct in_addr inp;
        r1=inet_addr(str);
        if(r1==-1){
                printf("inet_addr return -1 when 255.255.255.255\n");
        }else{
                printf("inet_addr:ip=%lu\n",ntohl(r1));
        }
        r2=inet_network(str);
        if(r2==-1){
                printf("inet_network return -1 when 255.255.255.255\n");
        }else{
                printf("inet_network:ip=%lu\n",r2);
        }
        r3=inet_aton(str,&inp);
        if(r3==0){
                printf("inet_aton return -1 when 255.255.255.255\n");
        }else{
                printf("inet_aton:ip=%lu\n",ntohl(inp.s_addr));
        }
        return 0;
}

你肯定會理解的,只要把str的值稍微修改修改,你就可以得到不同的結果,從而看出其中玄機~~:)
over~

 

inet_aton,inet_addr和inet_ntoa在點分十進制數串(如,“192.168.1.10")與他的32位網絡字節二進制值之前轉換IPV4地址,有2個比較新的函數inet_pton和inet_ntop,這2個對IPV4和IPV6地址都能處理
       #include 
       #include 
       #include 
       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 structure 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 subsequent calls will overwrite.
inet_ntoa 函數轉換網絡字節排序的地址為標准的ASCII以點分開的地址,,該函數返回指向點分開的字符串地址的指針,該字符串的空間為靜態分配的,這意味着在第二次調用該函數時,上一次調用將會被重寫(復蓋),所以如果需要保存該串最后復制出來自己管理!

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

有兩個更新的函數inet_pton和inet_ntop這2個函數能夠處理ipv4和ipv6,原型如下
#include 
#include 
#include 
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 
#include 
#include 
const char *inet_ntop(int af, const void *src, char *dst, socklen_t cnt);
這個函數轉換網絡二進制結構到ASCII類型的地址,參數的作用和上面相同,只是多了一個參數socklen_t cnt,他是所指向緩存區dst的大小,避免溢出,如果緩存區太小無法存儲地址的值,則返回一個空指針,並將errno置為ENOSPC

例子:
#include 
#include 
#include 
#include 

int main(void)
{
    char* ip = "192.168.1.87";
    struct in_addr inp;
    u_int32_t addr = 0x5701a8c0;
    inet_aton(ip, &inp);
    printf("%x ", inp);
    inp.s_addr = addr;
    printf("%s \n", inet_ntoa(inp));
    return 0;
}


免責聲明!

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



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