Função getaddrinfo na linguagem C

Função getaddrinfo na linguagem C

Para abrir um servidor de cliente do soquete, precisamos de algumas informações importantes sobre o servidor para o qual queremos conectar, como o endereço do domínio, a família de endereços que ele usa, etc.

Esse processo de conexão requer o uso de várias funções, e a chamada para cada uma delas tem uma ordem específica que deve ser seguida estritamente. Muitas dessas funções são usadas para recuperar os dados do servidor para o qual você deseja se conectar. Seus resultados são alguns dos argumentos de entrada para a função subsequente.

Esses argumentos são descritores e estruturas de dados que contêm informações específicas do cliente e do servidor sobre algumas das camadas que compõem uma conexão de rede.

Nisso Linux Dica artigo, você aprenderá a usar o getaddrinfo () função para resolver o endereço IP de um nome de host e obter as informações necessárias nas estruturas de dados que as várias funções C usam para se conectar a um servidor remoto.

Veremos uma descrição da sintaxe, argumentos e estruturas de entrada/saída que compõem essa função, bem como uma explicação teórica de como ela funciona. Em seguida, aplicaremos o que aprendemos em um exemplo prático que inclui trechos de código e imagens que mostram como usar o getaddrinfo () função em c.

O uso desta função requer uma compreensão das estruturas de dados que compõem seus argumentos de entrada. Por esse motivo, incluímos uma seção especial neste artigo que descreve sua composição, o tipo de dados de seus membros, o parâmetro que é definido por cada um deles e a modificação deste parâmetro.

Sintaxe da função getaddrinfo () na linguagem C

int getaddrinfo (const char *nó,
Const Char *Serviço,
const struct addrinfo *dicas,
struct addrinfo ** res);

Descrição da função getaddrinfo () na linguagem C

O getaddrinfo () A função resolve o endereço IP de um domínio e executa uma informação cruzando com o servidor para os dados básicos necessários para abrir um soquete e estabelecer uma comunicação com ele.

O endereço IP que é resolvido por esta função é armazenado em estruturas do tipo Sockaddr, o mesmo tipo usado pelas funções Bind () e Connect () para estabelecer a conexão.

Para entender melhor como o getaddrinfo () funciona, precisamos saber quais são seus argumentos de entrada. A seguir, é apresentada uma lista desses argumentos, juntamente com uma explicação da função que cada um deles executa no getaddrinfo ():

nó: Uma string, ou um ponteiro, que especifica o nome de domínio ou o endereço IP da qual queremos obter as informações. Se o nó é um nome de host, getaddrinfo () resolve seu endereço IP. Este argumento de entrada aceita um nome IPv4, IPv6 ou domínio.

serviço: Uma string ou um ponteiro para ela que especifica o tipo de serviço ou o número da porta através do qual o soquete deve ser conectado. Este argumento de entrada pode ser passado como nulo, desde que o nó especifique um nome de host válido ou endereço.

dicas: Este argumento de entrada é uma estrutura de addrinfo digite onde cada um de seus membros especifica o nome do domínio e o tipo de conexão a ser feita no servidor. Esses parâmetros fornecem informações sobre, por exemplo, o protocolo de transporte, a versão IP que pretendemos usar, etc. Dessa forma, as informações fornecidas pelo servidor são direcionadas para esse tipo de conexão, se possível. Mais tarde, veremos uma seção sobre essa estrutura, os parâmetros individuais estabelecidos por seus membros e como configurar a conexão através deles.

res: Este argumento é uma estrutura do tipo addrinfo no qual as informações que são retornadas pelo servidor são armazenadas. Res contém uma estrutura e um ponteiro para essa estrutura ou uma lista de estruturas do tipo de soja que armazenam o endereço do nome do host que é enviado em e resolvido pelo servidor. Esta estrutura contém o mesmo tipo de informação de dicas em seus membros, mas com os dados do servidor. Esta informação é então usada como um argumento de entrada para as funções Bind () e Connect () para estabelecer a conexão.

Nos casos em que o servidor retorna mais de um endereço, cada um pode ser acessado com o ai_next ponteiro que é um membro do res estrutura.

Se o getaddrinfo () função obtém com sucesso as informações, ele retorna 0. Se ocorrer um erro, esta função retorna o código de uma lista definida no “netdb.H ”cabeçalho.

Mais tarde, você encontrará uma seção que lida com erros ao usar essa função e as definições com suas respectivas representações numéricas que são retornadas por getaddrinfo ().

O getaddrinfo () A função é definida no “netdb.H ”cabeçalho. Para usá -lo, ele deve ser incluído em nosso código da seguinte forma:

#incluir

Como resolver o endereço IP de um domínio usando a função getaddrinfo () em c

Neste exemplo, explicaremos como resolver o endereço IP de um domínio e obter os parâmetros necessários do servidor nas estruturas Addrinfo e Sockaddr para estabelecer uma conexão cliente-servidor com ele.

O primeiro passo é definir as estruturas e variáveis ​​necessárias para os argumentos de entrada e saída de getaddrinfo (). Em seguida, vejamos a definição das variáveis ​​que usaremos neste exemplo e a maneira correta de declarar o addrinfo Estruturas:

em terror;
Char HostName [100] = "www.Linuxhints.com ";
struct addrinfo dicas_1, *res_1;


O erro variável é o argumento de saída de getaddrinfo (). Usamos para detectar os possíveis erros. O nome de anfitrião Array de caracteres contém a string com o nome do domínio e é o argumento de entrada, nó.

O Hints_1 "Sugere" ao servidor o tipo de conexão que queremos fazer. RES_1 é a estrutura que getaddrinfo () Retorna com os dados do servidor e o endereço de domínio.

É importante que você defina todos os parâmetros do Hints_1 estrutura para caracteres nulos. Neste exemplo, usamos a função MEMSET () para definir o espaço que é alocado a essa estrutura para o caráter nulo.

Depois que as variáveis ​​e estruturas são definidas, chamamos o getaddrinfo () função e passar o nome de anfitrião Array como um argumento de entrada, , com o nome de domínio cujo endereço IP queremos obter. Nesse caso, usamos o endereço do nosso site - “Www .Linuxhint.com ”

No argumento de entrada serviço, Podemos especificar que o serviço solicitado é "http" ou o número 80 da porta, que é o mesmo.

O terceiro e quarto argumentos de entrada são as estruturas Hints_1 e res_1, respectivamente.

O argumento de saída é erro que usamos para determinar se getaddrinfo () retorna com erros ou executa a operação com sucesso.

Se getaddrinfo () retorna com sucesso, as estruturas que são apontadas por res_1 conter o endereço IP correspondente ao domínio especificado e a quaisquer parâmetros de servidor necessários para as funções Bind () e Connect () no Sockaddr Digite estruturas para se conectar a ele.

Para descobrir se ocorre um erro, produzimos o resultado no console de comando. Em seguida, vemos o código completo para este exemplo, que inclui os cabeçalhos, define as variáveis ​​e estruturas e chama o getaddrinfo () função.

#incluir
#incluir
#incluir
int main ()

em terror;
Char HostName [100] = "www.Linuxhints.com ";
struct addrinfo dicas_1, *res_1;
MEMSET (& HINTS_1, '\ 0', sizeof (hints_1));
erro = getaddrinfo (nome do host, "80", & hints_1, & res_1);
printf ("\ nerror: %i \ n", erro);


Como podemos ver na imagem a seguir, a função Getaddrinfo retorna sem erros:

Como converter o endereço IP retornado pelo servidor em uma estrutura de estrutura addrinfo para string

Em muitos casos, é útil converter o endereço IP que é retornado pelo servidor quando a função getaddrinf () é chamada para uma string. Este endereço é armazenado na matriz de caracteres de 14 elementos, sa_data, Na estrutura de demão, que é um membro da estrutura RES do tipo addrinfo.

Embora o endereço seja armazenado em uma variedade de elementos de Caracteres Tipo, eles não têm formato de caráter, mas uma representação numérica de números inteiros de 0 a 255.

Na família IP V4, o primeiro valor do sa_data a matriz é sempre zero e o segundo valor é o número da porta. Portanto, os elementos que precisamos converter são 2, 3, 4 e 5.

Realizamos a conversão usando a função INT_ntop (). Esta função converte os números binários na matriz SA_DATA em caracteres e os devolve na matriz IP.

Como os bytes que especificam o número de IP começam com o byte número 2, nos referimos a esse endereço como um ponteiro para SA_DATA no argumento de entrada SRC da função INET_NTOP ().

#incluir
Char IP não assinado [50] = "";
if (erro == 0)
inet_ntop (af_inet, & res_1-> ai_addr-> sa_data [2], ip, sizeof (ip));
printf ("Endereço IP: %S \ n \ n", IP);


Se inserirmos esse fragmento no final do código do exemplo anterior, vemos o IP correspondente ao nome do host que enviamos ao servidor para resolver seu endereço.

#incluir
#incluir
#incluir
int main ()

int a;
char não assinado b [5] = "";
Char IP não assinado [50] = "";
em terror;
Char HostName [100] = "www.Linuxhints.com ";
struct addrinfo dicas_1, *res_1;
MEMSET (& HINTS_1, '\ 0', sizeof (hints_1));
erro = getaddrinfo (nome do host, "80", & hints_1, & res_1);
printf ("\ nerror: %i \ n", erro);
#incluir
Char IP não assinado [50] = "";
if (erro == 0)
inet_ntop (af_inet, & res_1-> ai_addr-> sa_data [2], ip, sizeof (ip));
printf ("Endereço IP: %S \ n \ n", IP);


Na figura a seguir, vemos o endereço IP correspondente ao nome do host que recuperamos da estrutura addrinfo res_1 e convertem em uma string para inet_ntop ():

Estrutura addrinfo

Os membros do addrinfo A estrutura é responsável por informar o servidor sobre certos parâmetros do soquete a serem abertos. Esses parâmetros são especificados na estrutura que é enviada como argumentos de entrada em dicas. O servidor responde enviando as informações armazenadas em uma estrutura semelhante cujo ponteiro é enviado como um argumento de entrada em res.

As informações retornadas são uma configuração que corresponde ou é mais próxima da configuração que é sugerida em dicas com base nos recursos do servidor. Por exemplo, se você deseja criar uma configuração para endereços IPv6, nem todos os servidores podem lidar com esse tipo de família.

Em seguida, olhamos em detalhes para os elementos individuais da estrutura e quais parâmetros eles definem.

estrutura addrinfo

int ai_flags; /* Sinalizadores de entrada. */
int ai_family; /* Família de protocolo para soquete. */
int ai_socktype; /* Tipo de soquete. */
int ai_protocol; /* Protocolo para soquete. */
socklen_t ai_addrlen; /* Comprimento do endereço do soquete. */
struct Sockaddr *ai_addr; /* Endereço do soquete para soquete. */
char *ai_cannonname; /* Nome canônico para localização do serviço. */
struct addrinfo *ai_next; /* Ponteiro para o próximo na lista. */
;


Vamos dar uma olhada detalhada nos seguintes campos individuais da estrutura Addrinfo e nas opções de parâmetros para cada campo:

ai_flags: Estes são sinalizadores de controle que são agrupados em um número inteiro. Para definir um deles como 0 ou 1, você deve realizar uma operação lógica bit -bit -in entre o número inteiro e uma máscara que muda apenas os bits selecionados. Em nosso artigo, “Operadores Bitwise em C”, explicamos passo a passo sobre como executar as operações lógicas com máscaras.

Em seguida, vejamos o fragmento do “netdb.H ”Cabeçalho onde essas bandeiras são definidas com uma breve descrição de cada uma:

/* Valores possíveis para o campo 'ai_flags' na estrutura 'addrinfo'. */
# Definir ai_passive 0x0001 // O endereço é destinado a 'Bind'.
# Definir ai_canonname 0x0002 // Solicitação de nome canônico.
# Definir ai_numerichost 0x0004 // Não use resolução de nomes.
# Definir AI_V4MaPed 0x0008 // Endereços mapeados IPv4.
# Definir ai_all 0x0010 // Retornar IPv4 mapeado e IPv6
# Definir ai_addrconfig 0x0020 // Use a configuração deste host
// escolher
// Tipo de endereço retornado.
# ifdef __use_gnu
# Definir ai_idn 0x0040 // idn codificar entrada // na localidade atual
// conjunto de personagens (colação)
// antes de procurar.
# Definir ai_canOidn 0x0080 // traduzir o nome canônico de
// formato idn.
# Definir ai_idn_allow_unassignado 0x0100 // não rejeite não atribuído
// pontos de código Unicode.
# Definir ai_idn_use_std3_ascii_rules 0x0200 // validar strings
// de acordo com
// regras STD3.


Manipular as bandeiras sem conhecimento total pode levar a erros difíceis de diagnosticar. Portanto, é aconselhável usar este campo em sua configuração padrão.

ai_family: Este número inteiro especifica uma das duas opções familiares de endereço que o servidor deve retornar. As opções da família de endereço são:

AF_INET para endereços IPv4.

AF_INET6 para endereços IPv6.

AF_UNSPEC pode devolver qualquer uma das duas famílias.

ai_socktype: Este número inteiro define o protocolo de transporte para o soquete. As opções de tipo são:

Sock_stream para protocolo TCP

Sock_dgram para protocolo UDP

ai_addrlen: Este campo indica o tamanho do endereço do soquete.

Ai_addr: Nesta estrutura do tipo demão, o endereço do soquete é armazenado.

ai_next: Se o servidor tiver mais de um endereço, ele retornará várias estruturas do tipo Sockaddr, cada uma contendo um endereço diferente. O ai_next é o ponteiro da lista de estruturas que você pode usar para acessar cada estrutura.

Como definir os parâmetros do soquete nos campos do Addrinfo struct

Os parâmetros da estrutura Addrinfo devem ser definidos antes de ligar para o getaddrinfo (). Você pode alterá -los da seguinte maneira:

Nome da estrutura . campo = valor;


Por exemplo, se queremos selecionar a família de endereços IPv6 na estrutura RES_1 do exemplo anterior, precisamos fazer o seguinte:

res_1 . ai_family = af_inet6

Erros retornados pela função getaddrinfo () na linguagem C

Se ocorrer um erro quando o getaddrinfo () A função é chamada, retorna um valor numérico indicando qual é o erro. Em seguida, vemos um fragmento do “netdb.H ”Cabeçalho onde esses erros e sua representação numérica são definidos.

/* Valores de erro para a função 'getaddrinfo'. */
# Definir eai_badflags -1 // Valor inválido para 'ai_flags' Campo.
# define eai_noname -2 // nome ou serviço é desconhecido.
# Definir eai_again -3 // falha temporária na resolução de nomes.
# Definir eai_fail -4 // falha não recobrável no nome res.
# Definir eai_family -6 // 'ai_family' não suportado.
# define eai_socktype -7 // 'ai_socktype' não suportado.
# Definir EAI_SERVICE -8 // Serviço não suportado ai_socktype '
# Definir EAI_MEMORY -10 // Falha na alocação de memória.
# Definir EAI_SYSTEM -11 // Erro do sistema retornado em 'errno'.
# Definir EAI_OVERFLOW -12 // Buffer de argumento Overflow.
# ifdef __use_gnu
# Definir eai_nodata -5 // nenhum endereço associado ao nome.
# Definir EAI_ADDRFAMILY -9 // Família de endereço para nome não suportado.
# Definir EAI_INPROGRESS -100 // Solicitação de processamento em andamento.
# Definir EAI_CANCELED -101 // Solicitação cancelada.
# define eai_notcanceled -102 // solicitação não cancelada.
# Definir eai_alldone -103 // todas as solicitações feitas.
# define eai_intr -104 // interrompido por um sinal.
# define eai_idn_encode -105 // codificação IDN falhou.

Conclusão

Nisso Linux dicas artigo, explicamos como usar o getaddrinfo () função para resolver o endereço IP de um domínio e obter as informações necessárias do servidor para abrir um soquete e se conectar a ele.

Analisamos a sintaxe desta função e descrevemos cada um de seus argumentos de entrada, o tipo de dados utilizados neles e seu propósito dentro da função em detalhes. Para ajudá -lo a entender como lidar com essa função, criamos duas seções especiais explicando como as estruturas Addrinfo são construídas, quais parâmetros fazem cada um de seus membros lida e como você pode alterá -los para configurar a conexão.

Esperamos que você tenha achado este artigo útil. Para mais artigos sobre o idioma C e Linux dicas, Por favor, use o mecanismo de pesquisa em nosso site.