inet_aton和inet_ntoa

3.1 inet_aton()

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

  • 參數說明:

  • cp : IPv4點分十進制字符串,例如“192.168.1.2”、“10.28.1.1”等;

  • inp: 點分十進制轉換成二進制後的結構體(網絡字節序)

  • 返回值:成功返回非0;失敗返回0

注意:

這個函數已經將inp轉換爲網絡字節序;已經將inp轉換爲網絡字節序;已經將inp轉換爲網絡字節序;

  • 舉例說明:
int inet_aton_demo()
{
    char *string="192.168.1.2";
    struct in_addr ip={0};
    unsigned char *c=NULL;
    int integer=0xc0a80102;/*用來對比測試*/

    if(!inet_aton(string, &ip)){
        printf("%s:%d error\n", __func__, __LINE__);
        return -1;
    }
    printf("%8.8x ---- %u\n", ip.s_addr, ip.s_addr);/**/
    c=(char *)&ip.s_addr;
    printf("%2.2x ---- %2.2x --- %2.2x --- %2.2x\n", *c, *(c+1), *(c+2), *(c+3));

    printf("%8.8x ---- %u\n", integer, integer);/**/
    c=(char *)&integer;
    printf("%2.2x ---- %2.2x --- %2.2x --- %2.2x\n", *c, *(c+1), *(c+2), *(c+3));
}

編譯運行,結果如下:

root@ubantu:/mnt/hgfs/em嵌入式學習記錄/schedule調度器# ./demo.out 
0201a8c0 ---- 33663168			
c0 ---- a8 --- 01 --- 02		--->inet_aton()轉換後的字節序

c0a80102 ---- 3232235778
02 ---- 01 --- a8 --- c0		--->正常的主機字節序
root@ubantu:/mnt/hgfs/em嵌入式學習記錄/schedule調度器# 

從上述結果可以看出:

inet_aton()會將點分十進制的字符串轉換爲網絡字節序的二進制數。此時如果要做網絡用途使用的話,無需再次轉換(即,無需再通過htonl做轉換);但是如果想在本地上查看轉換後的結果,則需要做一個轉換(需要使用ntohl)。

3.2 inet_ntoa()

char *inet_ntoa(struct in_addr in);

  • 參數說明:

  • inp: 點分十進制轉換成二進制後的結構體(網絡字節序)

  • 返回值 : IPv4點分十進制字符串指針,例如“192.168.1.2”、“10.28.1.1”等;

注意:

不可重入,不可重入,不可重入

​ 因爲轉換後的字符串使用同一塊靜態內存區,再次調用會被覆蓋。

  • 舉例說明:
int inet_ntoa_demo()
{
    char *string=NULL;
    struct in_addr ip;
    unsigned char *c=NULL;

    ip.s_addr = 0xc0a80102;
    /*
    * 1. char *inet_ntoa(struct in_addr in);
    */

    if(!(string=inet_ntoa(ip))){
        printf("%s:%d %s\n", __func__, __LINE__, strerror);
        return -1;
    }
    printf("%s\n", string);
    printf("%8.8x ---- %u\n", ip.s_addr, ip.s_addr);/**/
    c=(char *)&ip.s_addr;
    printf("%2.2x ---- %2.2x --- %2.2x --- %2.2x\n", *c, *(c+1), *(c+2), *(c+3));


    ip.s_addr = htonl(0xc0a80102);/*轉換爲網絡字節序*/
    if(!(string=inet_ntoa(ip))){
        printf("%s:%d %s\n", __func__, __LINE__, strerror);
        return -1;
    }
    printf("%s\n", string);
    printf("%8.8x ---- %u\n", ip.s_addr, ip.s_addr);/**/
    c=(char *)&ip.s_addr;
    printf("%2.2x ---- %2.2x --- %2.2x --- %2.2x\n", *c, *(c+1), *(c+2), *(c+3));


    /*
        root@ubantu:/mnt/hgfs/em嵌入式學習記錄/schedule調度器# ./demo.out 
        0201a8c0 ---- 33663168
        c0 ---- a8 --- 01 --- 02
        root@ubantu:/mnt/hgfs/em嵌入式學習記錄/schedule調度器# 
    */
}

編譯運行,結果如下:

root@ubantu:/mnt/hgfs/em嵌入式學習記錄/schedule調度器# ./demo.out 
2.1.168.192					
c0a80102 ---- 3232235778			---主機字節序
02 ---- 01 --- a8 --- c0

192.168.1.2
0201a8c0 ---- 33663168				---網絡字節序
c0 ---- a8 --- 01 --- 02
root@ubantu:/mnt/hgfs/em嵌入式學習記錄/schedule調度器# 

從上述結果可以看出:

inet_ntoa()會將二進制數以網絡字節序的方式解析爲點分十進制字符串。因此我們再定義in_addr變量時,直接將其s_addr的值轉換爲網絡字節序;但是如果想在本地上查看轉換後的結果,則需要做一個轉換(需要使用ntohl)。

小結: 使用in_addr.s_addr時,這個值裏存儲的應該一直爲網絡字節序。本地想查看該變量的值,應作一次ntohl轉換;如果做網絡收發等等,則無需做任何轉換。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章