Función GetAddrinfo en lenguaje C

Función GetAddrinfo en lenguaje C

Para abrir un servidor cliente de Socket, necesitamos información importante sobre el servidor al que queremos conectarnos, como la dirección de dominio, la familia de direcciones que usa, etc.

Este proceso de conexión requiere el uso de varias funciones, y la llamada a cada uno de estos tiene un orden específico que debe seguirse estrictamente. Muchas de estas funciones se utilizan para recuperar los datos del servidor a los que desea conectarse. Sus resultados son algunos de los argumentos de entrada para la función posterior.

Estos argumentos son descriptores y estructuras de datos que contienen la información específica del cliente y el servidor sobre algunas de las capas que componen una conexión de red.

En esto Pista de Linux artículo, aprenderá cómo usar el getAddrinfo () Función para resolver la dirección IP de un nombre de host y obtener la información necesaria en las estructuras de datos que las diversas funciones C usan para conectarse a un servidor remoto.

Veremos una descripción de la sintaxis, los argumentos y las estructuras de entrada/salida que componen esta función, así como una explicación teórica de cómo funciona. Luego, aplicaremos lo que aprendimos en un ejemplo práctico que incluye fragmentos e imágenes de código que muestran cómo usar el getAddrinfo () función en c.

El uso de esta función requiere una comprensión de las estructuras de datos que componen sus argumentos de entrada. Por esta razón, incluimos una sección especial en este artículo que describe su composición, el tipo de datos de sus miembros, el parámetro establecido por cada uno de ellos y la modificación de este parámetro.

Sintaxis de la función getaddrinfo () en lenguaje C

int getaddrinfo (const char *nodo,
Servicio const Char *,
constre struct adrinfo *sugerencias,
struct adrinfo ** res);

Descripción de la función getaddrinfo () en el idioma C

El getAddrinfo () La función resuelve la dirección IP de un dominio y realiza un cruce de información con el servidor para los datos básicos que se necesitan para abrir un socket y establecer una comunicación con él.

La dirección IP que resuelve esta función se almacena en estructuras del tipo SockAdDR, el mismo tipo que utiliza las funciones bind () y Connect () para establecer la conexión.

Para comprender mejor cómo funciona getAddrinfo (), necesitamos saber cuáles son sus argumentos de entrada. La siguiente es una lista de estos argumentos junto con una explicación de la función que cada uno de ellos realiza dentro de getaddrinfo ()::

nodo: Una cadena, o un puntero, que especifica el nombre de dominio o la dirección IP de la que queremos obtener la información de la información. Si el nodo es un nombre de host, getAddrinfo () Se resuelve a su dirección IP. Este argumento de entrada acepta un nombre de dominio IPv4, IPV6 o de dominio.

servicio: Una cadena o un puntero que especifica el tipo de servicio o el número de puerto a través del cual se debe conectar el socket. Este argumento de entrada puede aprobarse tan nulo siempre que el nodo especifique un nombre de host o dirección válido.

Sugerencias: Este argumento de entrada es una estructura de complemento Escriba donde cada uno de sus miembros especifica el nombre de dominio y el tipo de conexión que se realizará al servidor. Estos parámetros proporcionan información sobre, por ejemplo, el protocolo de transporte, la versión IP que pretendemos usar, etc. De esta manera, la información que proporciona el servidor está dirigida a este tipo de conexión, si es posible. Más tarde, veremos una sección sobre esta estructura, los parámetros individuales establecidos por sus miembros y cómo configurar la conexión a través de ellos.

Res: Este argumento es una estructura del tipo de adrinfo en el que se almacena la información que devuelve el servidor. Resonancia contiene una estructura y un puntero a esta estructura o una lista de estructuras de tipo Sockaddr que almacena la dirección del nombre de host que se envía en nodo y resuelto por el servidor. Esta estructura contiene el mismo tipo de información de pistas en sus miembros, pero con los datos del servidor. Esta información se usa como argumento de entrada para las funciones bind () y conectar () para establecer la conexión.

En los casos en que el servidor devuelve más de una dirección, se puede acceder a cada uno con el ai_next puntero que es miembro del resonancia estructura.

Si el getAddrinfo () la función obtiene con éxito la información, devuelve 0. Si se produce un error, esta función devuelve el código de una lista que se define en el "NetDB.encabezado.

Más tarde, encontrará una sección que se ocupa de los errores al usar esta función y las definiciones con sus respectivas representaciones numéricas que son devueltas por getAddrinfo ().

El getAddrinfo () la función se define en el "netdb.encabezado. Para usarlo, debe incluirse en nuestro código de la siguiente manera:

#incluir

Cómo resolver la dirección IP de un dominio utilizando la función getaddrinfo () en c

En este ejemplo, explicaremos cómo resolver la dirección IP de un dominio y obtendremos los parámetros necesarios del servidor en las estructuras de AdDrinfo y SockAddr para establecer una conexión de cliente cliente con él.

El primer paso es definir las estructuras y variables necesarias para los argumentos de entrada y salida de getAddrinfo (). A continuación, veamos la definición de las variables que usaremos en este ejemplo y la forma correcta de declarar el complemento Estructuras:

en terror;
Char hostName [100] = "www.Linuxhints.com ";
struct AdDrinfo Sints_1, *res_1;


El error variable es el argumento de salida de getAddrinfo (). Lo usamos para detectar los posibles errores. El nombre de host La matriz de caracteres contiene la cadena con el nombre de dominio y es el argumento de entrada, nodo.

El sugerencias_1 "Sugiere" al servidor el tipo de conexión que queremos hacer. RiñonalES_1 es la estructura que getAddrinfo () Devuelve con los datos del servidor y la dirección de dominio.

Es importante que establezca todos los parámetros del sugerencias_1 estructura a personajes nulos. En este ejemplo, usamos la función memset () para establecer el espacio que se asigna a esta estructura a carácter nulo.

Una vez que se definen las variables y estructuras, llamamos al getAddrinfo () función y pasar el nombre de host matriz como argumento de entrada, nodo, con el nombre de dominio cuya dirección IP queremos obtener. En este caso, utilizamos la dirección de nuestro sitio web - "www .Linuxhint.com "

En el argumento de entrada servicio, Podemos especificar que el servicio solicitado es "http" o el número de puerto 80, que es el mismo.

El tercer y cuarto argumentos de entrada son las estructuras sugerencias_1 y res_1, respectivamente.

El argumento de salida es error que usamos para determinar si getAddrinfo () Devuelve con errores o realiza la operación correctamente.

Si getAddrinfo () Devuelve con éxito, las estructuras que son señaladas por res_1 contener la dirección IP correspondiente al dominio especificado y cualquier parámetros del servidor necesarios por las funciones bind () y conecte () en el sockaddr Escriba estructuras para conectarse a él.

Para averiguar si se produce un error, generamos el resultado en la consola de comando. A continuación, vemos el código completo para este ejemplo que incluye los encabezados, define las variables y las estructuras y llama al getAddrinfo () función.

#incluir
#incluir
#incluir
int main ()

en terror;
Char hostName [100] = "www.Linuxhints.com ";
struct AdDrinfo Sints_1, *res_1;
MemSet (&ints_1, '\ 0', sizeof (INTRESTS_1));
error = getAddrinfo (hostname, "80", & tints_1, & res_1);
printf ("\ nerror: %i \ n", error);


Como podemos ver en la siguiente imagen, la función getAddrinfo regresa sin errores:

Cómo convertir la dirección IP devuelta por el servidor en una estructura de estructura de Addrinfo a cadena

En muchos casos, es útil convertir la dirección IP que devuelve el servidor cuando la función getAddrinf () se llama a una cadena. Esta dirección se almacena en la matriz de caracteres de 14 elementos, sa_data, En la estructura de SockAddr, que es un miembro de la estructura RES del tipo de Addrinfo.

Aunque la dirección se almacena en una variedad de elementos de carbonizarse Tipo, no tienen formato de carácter, sino una representación numérica de enteros de 0 a 255.

En la familia IP V4, el primer valor del sa_data La matriz siempre es cero y el segundo valor es el número de puerto. Entonces, los elementos que necesitamos para convertir son 2, 3, 4 y 5.

Realizamos la conversión utilizando la función inet_ntop (). Esta función convierte los números binarios en la matriz SA_DATA a caracteres y los devuelve en la matriz IP.

Dado que los bytes que especifican el número de IP comienzan con el número 2 del byte, nos referimos a esta dirección como un puntero a SA_DATA en el argumento de entrada SRC de la función inet_ntop ().

#incluir
Unsigned Char IP [50] = "";
if (error == 0)
inet_ntop (AF_Inet, & res_1-> ai_addr-> sa_data [2], ip, sizeof (ip));
printf ("Dirección IP: %s \ n \ n", ip);


Si insertamos este fragmento al final del código del ejemplo anterior, vemos la IP correspondiente al nombre de host que enviamos al servidor para resolver su dirección.

#incluir
#incluir
#incluir
int main ()

int a;
unsigned char b [5] = "";
Unsigned Char IP [50] = "";
en terror;
Char hostName [100] = "www.Linuxhints.com ";
struct AdDrinfo Sints_1, *res_1;
MemSet (&ints_1, '\ 0', sizeof (INTRESTS_1));
error = getAddrinfo (hostname, "80", & tints_1, & res_1);
printf ("\ nerror: %i \ n", error);
#incluir
Unsigned Char IP [50] = "";
if (error == 0)
inet_ntop (AF_Inet, & res_1-> ai_addr-> sa_data [2], ip, sizeof (ip));
printf ("Dirección IP: %s \ n \ n", ip);


En la siguiente figura, vemos la dirección IP correspondiente al nombre de host que recuperamos de la estructura ADDRINFO RES_1 y convertimos a una cadena para INET_NTOP ()::

Estructura adicional

Los miembros del complemento La estructura es responsable de informar al servidor sobre ciertos parámetros del socket que se abrirá. Estos parámetros se especifican en la estructura que se envía como argumentos de entrada en pistas. El servidor responde enviando la información que se almacena en una estructura similar cuyo puntero se envía como un argumento de entrada en resonancia.

La información devuelta es una configuración que coincide o está más cerca de la configuración que se sugiere en pistas Basado en las capacidades del servidor. Por ejemplo, si desea crear una configuración para las direcciones IPv6, no todos los servidores pueden manejar este tipo de familia.

A continuación, observamos en detalle los elementos individuales de la estructura y qué parámetros establecen.

estructura complinfo

int ai_flags; /* Indicadores de entrada. */
int ai_family; /* Familia de protocolo para el socket. */
int ai_socktype; /* Tipo de enchufe. */
int ai_protocol; /* Protocolo para socket. */
Socklen_t ai_addrlen; /* Longitud de la dirección del socket. */
struct sockaddr *ai_addr; /* Dirección de socket para socket. */
char *ai_cannonname; /* Nombre canónico para la ubicación del servicio. */
struct adrinfo *ai_next; /* Puntero al siguiente en la lista. */
;


Echemos un vistazo detallado a los siguientes campos individuales de la estructura de Addrinfo y las opciones de parámetros para cada campo:

ai_flags: Estas son banderas de control que se agrupan en un entero. Para establecer uno de ellos en 0 o 1, debe realizar una operación lógica bitwise entre el entero y una máscara que cambia solo los bits seleccionados. En nuestro artículo, "Operadores bitwise en C", explicamos paso a paso sobre cómo realizar las operaciones lógicas con máscaras.

A continuación, veamos el fragmento del "NetDB.encabezado H ”donde estas banderas se definen con una breve descripción de cada uno:

/* Valores posibles para el campo 'AI_FLAGS' en la estructura 'AdDrinfo'. */
# Define AI_Passive 0x0001 // La dirección está destinada a 'Bind'.
# Defina AI_CANONNAME 0x0002 // Solicitud de nombre canónico.
# Define AI_NUMERICHOST 0X0004 // No use la resolución de nombres.
# Defina AI_V4Mapped 0x0008 // direcciones asignadas por IPv4.
# Defina AI_ALL 0x0010 // Devuelve IPv4 asignado e IPv6
# Define AI_ADDRCONFIG 0x0020 // Use la configuración de este host
// elegir
// Tipo de dirección devuelto.
# ifdef __use_gnu
# Define AI_IDN 0x0040 // IDN Entrada de codificación // en la configuración regional actual
// Conjunto de personajes (Colación)
// antes de mirarlo.
# define ai_canoidn 0x0080 // traducir el nombre canónico de
// formato IDN.
# define ai_idn_allow_unassigned 0x0100 // No rechace sin asignar
// puntos de código unicode.
# Define ai_idn_use_std3_ascii_rules 0x0200 // validar cadenas
// de acuerdo a
// reglas std3.


Manipular las banderas sin pleno conocimiento puede conducir a errores que son difíciles de diagnosticar. Por lo tanto, es aconsejable usar este campo en su configuración predeterminada.

ai_family: Este número entero especifica una de las dos opciones familiares de direcciones que el servidor debe devolver. Las opciones de la familia de las direcciones son:

AF_INET para direcciones IPv4.

AF_INET6 para direcciones IPv6.

AF_UNSPEC puede devolver a cualquiera de las dos familias.

ai_socktype: Este entero establece el protocolo de transporte para el enchufe. Las opciones de tipo son:

Sock_stream para el protocolo TCP

SOCK_DGRAM para el protocolo UDP

ai_addrlen: Este campo indica el tamaño de la dirección del enchufe.

Ai_addr: En esta estructura de tipo de sockaddr, se almacena la dirección del enchufe.

AI_NEXT: Si el servidor tiene más de una dirección, devuelve múltiples estructuras de tipo SockAdDR, cada una con una dirección diferente. El AI_NEXT es el puntero de la lista de estructuras que puede usar para acceder a cada estructura.

Cómo establecer los parámetros de enchufe en los campos del Struct addrinfo

Los parámetros de la estructura de Addrinfo deben establecerse antes de llamar al getAddrinfo (). Puedes cambiarlos de la siguiente manera:

nombre de la estructura . campo = valor;


Por ejemplo, si queremos seleccionar la familia de direcciones IPv6 en la estructura res_1 del ejemplo anterior, necesitamos hacer lo siguiente:

res_1 . ai_family = AF_INET6

Errores devueltos por la función getaddrinfo () en el lenguaje C

Si se produce un error cuando el getAddrinfo () Se llama a la función, devuelve un valor numérico que indica cuál es el error. A continuación, vemos un fragmento del "NetDB.H "encabezado donde se definen estos errores y su representación numérica.

/* Valores de error para la función 'getAddrinfo'. */
# Define EAI_BADFLAGS -1 // Valor no válido para el campo 'AI_FLAGS'.
# Define EAI_NONAME -2 // se desconoce el nombre o el servicio.
# Defina EAI_AGAIN -3 // Falla temporal en la resolución de nombres.
# Define EAI_FAIL -4 // falla no recuperable en el nombre Res.
# Define EAI_FAMILY -6 // 'AI_FAMILY' no es compatible.
# define EAI_SOCKTYPE -7 // 'AI_SOCKTYPE' no es compatible.
# Define EAI_Service -8 // Servicio no es compatible con AI_SockType '
# Defina EAI_MEMORY -10 // Falla de asignación de memoria.
# Define EAI_SYSTEM -11 // Error del sistema devuelto en 'Errno'.
# define EAI_OVERFLOW -12 // desbordamiento del búfer de argumentos.
# ifdef __use_gnu
# Defina EAI_NODATA -5 // No hay dirección asociada con el nombre.
# Define EAI_ADDRFAMILY -9 // Dirección de familia para el nombre no es compatible.
# define EAI_InProgress -100 // Solicitud de procesamiento en progreso.
# Define EAI_CANCELED -101 // Solicitud cancelada.
# define EAI_NOTCANCELED -102 // Solicitud no cancelada.
# Defina EAI_ALLDONE -103 // Todas las solicitudes realizadas.
# Defina EAI_INTR -104 // interrumpido por una señal.
# Define EAI_IDN_ENCODE -105 // Fallado de codificación IDN.

Conclusión

En esto Sugerencias de Linux Artículo, explicamos cómo usar el getAddrinfo () función para resolver la dirección IP de un dominio y obtener la información necesaria del servidor para abrir un socket y conectarse a ella.

Observamos la sintaxis de esta función y describimos cada uno de sus argumentos de entrada, el tipo de datos utilizados en ellos y su propósito dentro de la función en detalle. Para ayudarlo a comprender cómo manejar esta función, creamos dos secciones especiales que explican cómo se construyen las estructuras de Addrinfo, qué parámetros maneja cada uno de sus miembros y cómo puede cambiarlas para configurar la conexión.

Esperamos que hayas encontrado este artículo útil. Para más artículos sobre el idioma C y Sugerencias de Linux, Utilice el motor de búsqueda en nuestro sitio web.