好记性不如铅笔头

C && C++, 编程

使用DNS函数获取IP地址简单代码笔记

话不多说,在网络编程中,我们一般都要对域名进行DNS解析,解析函数一般都是gethostbyname,但是这个函数已经被过时了,而且有多线程风险,现在官方建议使用getaddrinfo,那么这里我们就简单笔记下如何使用这2个API

#include <stdio.h>
#include <arpa/inet.h>
#include <netdb.h>

#define LOG printf

void test_gethostbyname(const char *p_hostname)
{
    LOG("test gethostbyname begin -->>\r\n");

    char **pptr = NULL;
    struct hostent *hptr = NULL;
    if( ( hptr = gethostbyname(p_hostname) ) == NULL )
    {
        LOG("gethostbyname error. errno:%d error:%s \r\n", h_errno, hstrerror(h_errno));
        return;
    }
    LOG("h_name:%s \r\n",hptr->h_name);
    LOG("h_aliases: \r\n");
    for(pptr = hptr->h_aliases; *pptr != NULL; pptr++)
        LOG("\t alias:%s \r\n", *pptr);

    LOG("h_length:%d \r\n",hptr->h_length);
    LOG("h_addrtype:%d \r\n",hptr->h_addrtype);
    switch(hptr->h_addrtype)
    {
        case AF_INET:
        {
            LOG("h_addr_list:\r\n");
            for(pptr=hptr->h_addr_list; *pptr != NULL; pptr++)
            {
                char str[INET_ADDRSTRLEN] = {0};
                LOG("\t addr:%s \r\n", inet_ntop(hptr->h_addrtype, *pptr, str, sizeof(str)) );
            }
            break;
        }
        default:
        {
            LOG("unknown h_addrtype:%d \r\n", hptr->h_addrtype);
            break;
        }
    }

    LOG("test gethostbyname finish <<--\r\n");
}

void test_getaddrinfo(const char *p_hostname)
{
    LOG("test getaddrinfo begin -->>\r\n");

    int result_code = 0;
    struct addrinfo hints, *addr_list, *cur;

    memset( &hints, 0, sizeof( hints ) );
    hints.ai_family = AF_UNSPEC;
    hints.ai_socktype = 0; // SOCK_STREAM  OR  SOCK_DGRAM
    hints.ai_protocol = 0; // IPPROTO_TCP  OR  IPPROTO_UDP
    hints.ai_flags = 0;

    if( ( result_code = getaddrinfo( p_hostname, NULL, &hints, &addr_list ) ) != 0 )
    {
        LOG("getaddrinfo error. result:%d error:%s \r\n", result_code, gai_strerror(result_code));
        return;
    }

    LOG("addr_list:\r\n");
    for( cur = addr_list; cur != NULL; cur = cur->ai_next )
    {
        LOG(">>>>>>> \r\n");
        LOG("\t ai_flags:%d \r\n", cur->ai_flags);
        LOG("\t ai_family:%d \r\n", cur->ai_family);
        LOG("\t ai_socktype:%d \r\n", cur->ai_socktype);
        LOG("\t ai_protocol:%d \r\n", cur->ai_protocol);
        LOG("\t ai_addrlen:%d \r\n", cur->ai_addrlen);
        struct sockaddr_in *addr = (struct sockaddr_in *)cur->ai_addr;
        char str[INET_ADDRSTRLEN] = {0};
        LOG("\t ai_addr:%s \r\n", inet_ntop(cur->ai_family, &addr->sin_addr, str, sizeof(str)) );
        LOG("\t ai_canonname:%s \r\n", cur->ai_canonname);
        LOG("<<<<<<< \r\n");
    }

    freeaddrinfo(addr_list);

    LOG("test getaddrinfo finish -->>\r\n");
}


void test_dns(const char *p_hostname)
{
    LOG("test hostname:%s \r\n", p_hostname);
    test_gethostbyname(p_hostname);
    test_getaddrinfo(p_hostname);
}


int main(int argc, char *argv[])
{
    test_dns(argv[1]);
    return 0;
}

 

发表评论

1 × 2 =

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据