Get host IP by domain name - struct addrinfo

Reference book: "Advanced Programming in UNIX Environment" (APUE, the book of the male god, the third edition is out, if you need it, you can send a private message to me)

Structure definition

The addrinfo structure is mainly used when analyzing hostname in network programming. It is defined as follows in the header file #include<netdb.h>:

struct addrinfo
{
    
    
  int ai_flags;                 /* Input flags.  */
  int ai_family;                /* Protocol family for socket.  */
  int ai_socktype;              /* Socket type.  */
  int ai_protocol;              /* Protocol for socket.  */
  socklen_t ai_addrlen;         /* Length of socket address.  */
  struct sockaddr *ai_addr;     /* Socket address for socket.  */
  char *ai_canonname;           /* Canonical name for service location.  */
  struct addrinfo *ai_next;     /* Pointer to next in list.  */
};

It can be said to be a new face or an old face, so let me introduce it?
Then introduce it: Okay, in fact, its introduction is quite clear.

Similar to sin_addr and s_addr.

Parameter definition:

ai_flags

Used to specify how to deal with addresses and names, the available values ​​are as follows:
Insert picture description here

Just change the prefix, right

ai_family

Insert picture description here

I don’t even change the prefix here

ai_socktype

Insert picture description here

Same as above

ai_protocol

IPPROTO_IP 	:IP协议
IPPROTO_IPV4 	:IPv4
IPPROTO_IPV6 	:IPv6
IPPROTO_TCP 	:TCP
IPPROTO_UDP	:UDP

There are many things in this change.

ai_next

Since a domain name can correspond to multiple IP addresses, addrinfo also supports this scenario. Addrinfo stores other addresses in a linked list, which can be obtained by traversing its attribute ai_next.

related functions

getaddrinfo

After looking around, I couldn't find its source code, so I could only post the statement, and then add it when I found it.

int getaddrinfo(const char *restrict nodename, /* host 或者IP地址 */
    const char *restrict servname, /* 十进制端口号 或者常用服务名称如"ftp"、"http"等 */
    const struct addrinfo *restrict hints, /* 获取信息要求设置 */
    struct addrinfo **restrict res); /* 获取信息结果 */

Parameter definition:

nodename:
host name ("lion-wu.blog.csdn.net") or a digitized address string (IPv4 dotted decimal string ("192.168.128.64") or IPv6 hexadecimal string).
If the AI_NUMERICHOST flag is set in ai_flags, then this parameter can only be a digitized address string, not a domain name. The function of this flag is to prevent domain name resolution.
The nodename and servname can be set to NULL, but only one of them can be NULL at the same time.

servname: The
service name can be a decimal port number ("8080") string, or a defined service name, such as "ftp", "http", etc. Please check the /etc/services file for details, and finally translate it into the corresponding The port number of the service. If this parameter is set to NULL, the port number in the returned socket address will not be set.
If the AI_NUMERICSERV flag is set in ai_flags and the parameter is not set to NULL, then the parameter must be a decimal port number string and cannot be set as a service name. This flag is used to prevent service name parsing.

hints:
This parameter points to the struct addrinfo structure set by the user. Only the four fields of ai_family, ai_socktype, ai_protocol and ai_flags can be set in this structure. The other fields must be set to 0 or NULL, usually used after applying for structure variables memset() initializes and then sets the specified four fields.
This parameter can be set to NULL, which is equivalent to ai_socktype = 0, ai_protocol = 0, ai_family = AF_UNSPEC, ai_flags = 0.

res:
This parameter obtains a struct addrinfo structure list that points to the storage result, and calls freeaddrinfo() after use to release the storage result space.

return value

If the getaddrinfo() function is executed successfully, the return value is 0. In other cases, the return value indicates the type of error. Use the function gai_strerror() to get readable error information, and the usage is the same as strerror().

chestnut

 ret = getaddrinfo("lion-wu.blog.csdn.net", NULL, &hint, &res);
    if (ret != 0) 
    {
    
    
        printf("getaddrinfo error\n");
        return -1;
    }

freeaddrinfo

void freeaddrinfo(struct addrinfo *ai)
{
    
    
    struct addrinfo *next;

#if defined(__BIONIC__)
    if (ai == NULL) return;
#else
    _DIAGASSERT(ai != NULL);
#endif

    do {
    
    
        next = ai->ai_next;
        if (ai->ai_canonname)
            free(ai->ai_canonname);
        /* no need to free(ai->ai_addr) */
        free(ai);
        ai = next;
    } while (ai);
}

Usage example

#include <stdlib.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <string.h>
#include <stdio.h>

int main(int argc, char **argv)
{
    
    
    int ret = -1;
    struct addrinfo *res;
    struct addrinfo hint;
    struct addrinfo *curr;
    char ipstr[16];   

    if (argc != 2) {
    
    
        printf("parameter error\n");
        return -1;
    }

    bzero(&hint, sizeof(hint));
    hint.ai_family = AF_INET;
    hint.ai_socktype = SOCK_STREAM;

    ret = getaddrinfo(argv[1], NULL, &hint, &res);
    if (ret != 0) 
    {
    
    
        printf("getaddrinfo error\n");
        return -1;
    }

    for (curr = res; curr != NULL; curr = curr->ai_next) 
    {
    
    
        inet_ntop(AF_INET,&(((struct sockaddr_in *)(curr->ai_addr))->sin_addr), ipstr, 16);
        printf("%s\n", ipstr);
    }

    freeaddrinfo(res);

    return 0;
}

Pro test:

Insert picture description here

Can you guess why the first operation failed?


Today's technical presentation on the matter here, I want to introduce one of my new friends:
Well ze lo boom Clang
our school chiefs Software Engineering, Java, algorithms, redis field bloggers, which are paid off.

Then, by the way, you can also check out my other blog, lion-wu.blog.csdn.net

Just swipe it and it's over, are you sure you don't leave it?
Insert picture description here

Insert picture description here

Guess you like

Origin blog.csdn.net/qq_43762191/article/details/108521905