Today's Question:  What does your personal desk look like?        GIVE A SHOUT

gethostbyname vs getaddrinfo

  sonic0002        2012-08-15 14:06:34       20,515        0    

getaddrinfo is slower than ping when resolving domain names. I think ping uses gethostbyname to resolve a domain name. The question becomes whether getaddrinfo is slower than gethostbyname. After testing with both functions, we find that getaddrinfo is really slow compared to gethostbyname. By strace tracking,  we find getaddrinfo will communicate with DNS server 10 times and gethostbyname will communicate with DNS server communication twice.

gethostbyname is an old way to resolve domain name, The disadvantage of it is that it does not support IPV6, so there is a gethostbyname2 which replaces gethostbyname, it supports both IPV4 and IPV6 resolving. Textbooks recommend to use getaddrinfo. The reason why it is slow is that getaddrinfo will resolve both IPV6 and IPv4 by default. If you set getaddrinfo only to resolve IPV4, the speed is the same as gethostbyname , it will communicate with DNS server twice

gethostbyname and getaddrinfo are bothworking in  blocked mode, C-ares library can be used to achieve asynchronous resolving.

When calling gethostbyname2 twice, respectively resolving IPV6 and IPv4, it's the equivalent of one call to getaddrinfo.

Testing code :

#include <stdio.h>
#include <string.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
 
#define HOST "cet.99sushe.com"
 
void print_time(const char *tip, const struct timeval *begin, const struct timeval *end)
{
    long diff = (end->tv_sec - begin->tv_sec) * 1000000 +
        (end->tv_usec - begin->tv_usec);
 
    printf("%s: %ld.%ld\n", tip, diff / 1000000, diff % 10000);
}
 
int main(int argc, char *argv[])
{
    struct timeval begin;
    struct timeval end;
 
    if (argc == 2 && strcmp(argv[1], "getaddrinfo") == 0) {
        struct addrinfo *ai;
        struct addrinfo hints;
 
        memset(&hints, 0x00, sizeof(hints));
        hints.ai_family   = AF_UNSPEC;
        hints.ai_socktype = SOCK_STREAM;
        hints.ai_protocol = 0;
        hints.ai_flags    = AI_NUMERICSERV;
 
        gettimeofday(&begin, 0);
        getaddrinfo(HOST, "80", &hints, &ai);
        gettimeofday(&end, 0);
 
        print_time("getaddrinfo", &begin, &end);
    }
 
    if (argc == 2 && strcmp(argv[1], "gethostbyname") == 0) {
        gettimeofday(&begin, 0);
        gethostbyname2(HOST, AF_INET);
        gethostbyname2(HOST, AF_INET6);
        gettimeofday(&end, 0);
 
        print_time("gethostbyname", &begin, &end);
    }
 
    return 0;
}
 

C++  NETWORK  DNS 

Share on Facebook  Share on Twitter  Share on Weibo  Share on Reddit 

  RELATED


  0 COMMENT


No comment for this article.