Obtener IP de host por nombre de dominio - struct addrinfo

Libro de referencia: "Programación avanzada en entorno UNIX" (APUE, el libro del dios masculino, la tercera edición está disponible, si lo necesita, puede enviarme un mensaje privado)

Definición de estructura

La estructura addrinfo se utiliza principalmente al analizar el nombre de host en la programación de la red. Se define de la siguiente manera en el archivo de encabezado #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.  */
};

Se puede decir que es una cara nueva o una cara vieja, así que déjame presentarla.
Entonces preséntalo: Vale, de hecho, su introducción es bastante clara.

Similar a sin_addr y s_addr.

Definición de parámetros:

ai_flags

Usados ​​para especificar cómo tratar con direcciones y nombres, los valores disponibles son los siguientes:
Inserte la descripción de la imagen aquí

Solo cambia el prefijo, ¿verdad?

ai_family

Inserte la descripción de la imagen aquí

Ni siquiera cambio el prefijo aquí

ai_socktype

Inserte la descripción de la imagen aquí

Lo mismo que arriba

ai_protocol

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

Hay muchas cosas en este cambio.

ai_next

Dado que un nombre de dominio puede corresponder a varias direcciones IP, addrinfo también admite este escenario. Addrinfo almacena otras direcciones en una lista vinculada, que se puede obtener atravesando su atributo ai_next.

funciones relacionadas

getaddrinfo

Después de mirar a mi alrededor, no pude encontrar su código fuente, por lo que solo pude publicar la declaración y luego agregarla cuando la encontré.

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

Definición de parámetros:

nodename:
nombre de host ("lion-wu.blog.csdn.net") o una cadena de dirección digitalizada (cadena decimal con puntos IPv4 ("192.168.128.64") o cadena hexadecimal IPv6).
Si la bandera AI_NUMERICHOST se establece en ai_flags, entonces este parámetro solo puede ser una cadena de dirección digitalizada, no un nombre de dominio. La función de esta bandera es evitar la resolución de nombres de dominio.
El nombre de nodo y el nombre de servicio se pueden establecer en NULL, pero solo uno de ellos puede ser NULL al mismo tiempo.

servname: el
nombre del servicio puede ser una cadena de número de puerto decimal ("8080") o un nombre de servicio definido, como "ftp", "http", etc. Por favor, consulte el archivo / etc / services para obtener más detalles y, finalmente, tradúzcalo al El número de puerto del servicio. Si este parámetro se establece en NULL, no se establecerá el número de puerto en la dirección de socket devuelta.
Si el indicador AI_NUMERICSERV se establece en ai_flags y el parámetro no se establece en NULL, entonces el parámetro debe ser una cadena de número de puerto decimal y no se puede establecer como un nombre de servicio. Este indicador se utiliza para evitar el análisis del nombre del servicio.

sugerencias:
Este parámetro apunta a la estructura struct addrinfo establecida por el usuario. Solo los cuatro campos de ai_family, ai_socktype, ai_protocol y ai_flags se pueden configurar en esta estructura. Los otros campos deben establecerse en 0 o NULL, generalmente usados ​​después de solicitar variables de estructura memset () inicializa y luego establece los cuatro campos especificados.
Este parámetro se puede establecer en NULL, que es equivalente a ai_socktype = 0, ai_protocol = 0, ai_family = AF_UNSPEC, ai_flags = 0.

res:
este parámetro obtiene una lista de estructura struct addrinfo que apunta al resultado de almacenamiento y llama a freeaddrinfo () después de su uso para liberar el espacio de resultados de almacenamiento.

valor de retorno

Si la función getaddrinfo () se ejecuta con éxito, el valor de retorno es 0. En otros casos, el valor de retorno indica el tipo de error. Use la función gai_strerror () para obtener información de error legible, y el uso es el mismo que strerror ().

castaña

 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);
}

Ejemplo de uso

#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;
}

Prueba profesional:

Inserte la descripción de la imagen aquí

¿Puedes adivinar por qué falló la primera operación?


Presentación técnica de hoy sobre el tema aquí, quiero presentarles a uno de mis nuevos amigos:
Bueno ze lo boom Clang
nuestros jefes de escuela Ingeniería de software, Java, algoritmos, bloggers de campo de redis, que están pagados.

Entonces, por cierto, también puedes consultar mi otro blog, lion-wu.blog.csdn.net

Simplemente deslícelo y se acabó, ¿está seguro de que no lo deja?
Inserte la descripción de la imagen aquí

Inserte la descripción de la imagen aquí

Supongo que te gusta

Origin blog.csdn.net/qq_43762191/article/details/108521905
Recomendado
Clasificación