C語言中實現inet_aton和inet_ntoa函數功能

來源:互聯網
上載者:User

之前遇到過要自己實現inet_aton和inet_ntoa函數功能的問題,這裡總結一下。

1 基本知識

網路位元組序是大端模式,那麼記憶體中的低地址存放的是資料的高位,記憶體中的高地址存放的是資料的低位。 inet_aton是將IPv4地址(點分法)轉換成對應的十進位整數;而inet_ntoa是將十進位整數轉換成對應的IPv4地址(點分法)。

2 完整代碼

#include <stdio.h>
#include <ctype.h>
#include "print.h"
#define IP_ADRESS "192.168.1.177"

/*
 * 將IPv4地址(點分法)轉換成對應的十進位整數
 * 原函式宣告:
 * int inet_aton(const char *cp, struct in_addr *inp);
 */
unsigned int __inet_aton( const char *c_ipaddr )
{
    unsigned int u_ipaddr = 0;
    unsigned int u_tmp = 0;
    char c;
    int i_base = 10;
    int i_shift = 0;
    int i_recycle = 0;

    c = *c_ipaddr;
    while( 1 )
    {
        u_tmp = 0;
        while( 1 )
        {
            //如果是數字
            if( isdigit(c) )
            {
                u_tmp = (u_tmp * i_base) + (c - 0x30);
                c = *++c_ipaddr;
            }
            else
            {
                //如果不是數字而是.符號,說明.符號前面的資料已經處理完畢
                break;
            }
        }

        //位元組移位,注意網路位元組序是大端模式
        i_shift = 8*i_recycle++;
        u_tmp <<= i_shift;
        u_ipaddr += u_tmp;

        //對點(.)符號的處理
        if( c == '.' )
        {
            c = *++c_ipaddr;
        }
        else
        {
            //如果是其它符號(例如結束符\0等)則跳出整個迴圈
            break;
        }
    }

    //檢查是否包含非結束符、空格等符號,是則返回0
    if( c != '\0' && ( !isspace(c) ) )
        goto ret_0;

    return u_ipaddr;
ret_0:
    return (0);
}

/**
 * 將十進位整數轉換成對應的IPv4地址(點分法),其中由於網路位元組序是大端表示,所以第一個位元組對應的是整數的低位byte[0]
 * 原函式宣告:
 * int inet_aton(const char *cp, struct in_addr *inp);
 */

static char buffer[16];
char *  __inet_ntoa( unsigned int in )
{
    unsigned char *bytes = (unsigned char *) &in;
    snprintf( buffer, sizeof (buffer), "%d.%d.%d.%d", bytes[0], bytes[1], bytes[2], bytes[3] );
    return buffer;
}

int main( int argc, char **argv )
{
    PRINT( "IP_ADRESS[%s] ==> [%lu].", IP_ADRESS, __inet_aton( IP_ADRESS ) );
    PRINT( "[%lu]=[0x%x].", __inet_aton( IP_ADRESS ), __inet_aton( IP_ADRESS ) );
    PRINT( "Network orders[%lu] ==> [%s].", __inet_aton( IP_ADRESS ), __inet_ntoa(__inet_aton( IP_ADRESS )) );
    return 0;
}


3 編譯執行

使用《Linux C/C++工程中可產生ELF、動/靜態庫檔案的通用Makefile》一文中的Makefile檔案進行程式編譯(當然也可以使用命令進行編譯gcc network_selfdefine.c -o network_selfdefine),接著執行該程式,得到如下圖所示的結果:

自己實現inet_aton和inet_ntoa函數功能

需要說明的是從第87行輸出的[2969675968]=[0xb101a8c0].可以看出,低位元組的0xC0(即192)由於網路位元組序大端模式的關係存放在記憶體中的高位,高位元組的0xB1(即177)存放在記憶體中的低位。

4 附錄

關於inet_aton的man說明:

[vfhky@typecodes xlei]$ man inet_aton
INET(3)                         Linux Programmer's Manual                        INET(3)

NAME
       inet_aton,   inet_addr,   inet_network,   inet_ntoa,  inet_makeaddr,  inet_lnaof,
       inet_netof - Internet address manipulation routines

SYNOPSIS
       #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);

       in_addr_t inet_network(const char *cp);

       char *inet_ntoa(struct in_addr in);

       struct in_addr inet_makeaddr(int net, int host);

       in_addr_t inet_lnaof(struct in_addr in);

       in_addr_t inet_netof(struct in_addr in);

   Feature Test Macro Requirements for glibc (see feature_test_macros(7)):

       inet_aton(), inet_ntoa(): _BSD_SOURCE || _SVID_SOURCE

DESCRIPTION
       inet_aton() converts the Internet host address cp from the IPv4  numbers-and-dots
       notation  into binary form (in network byte order) and stores it in the structure
       that inp points to.  inet_aton() returns nonzero if the address is valid, zero if
       not.


關於inet_aton的man說明:


[vfhky@typecodes ~]$ man inet_ntoa
INET(3)                         Linux Programmer's Manual                        INET(3)

NAME
       inet_aton,   inet_addr,   inet_network,   inet_ntoa,  inet_makeaddr,  inet_lnaof,
       inet_netof - Internet address manipulation routines

SYNOPSIS
       #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);

       in_addr_t inet_network(const char *cp);

       char *inet_ntoa(struct in_addr in);

       struct in_addr inet_makeaddr(int net, int host);

       in_addr_t inet_lnaof(struct in_addr in);

       in_addr_t inet_netof(struct in_addr in);

   Feature Test Macro Requirements for glibc (see feature_test_macros(7)):

       inet_aton(), inet_ntoa(): _BSD_SOURCE || _SVID_SOURCE

DESCRIPTION
       inet_aton() converts the Internet host address cp from the IPv4  numbers-and-dots
       notation  into binary form (in network byte order) and stores it in the structure
       that inp points to.  inet_aton() returns nonzero if the address is valid, zero if
       not.

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.