Quand je fais getaddrinfo pour localhost, je ne reçois pas 127.0.0.1
Je suis toujours en apprentissage et les sockets ne sais pas pourquoi cela n'a pas l'impression 127.0.0.1. Même si je remplace le mot localhost par 127.0.0.1 j'ai d'autres adresses ip qui je pense sont de mon routeur ou quelque chose. J'ai toujours pensé que ce doit retourner 127.0.0.1. Voici la sortie-je recevoir:
hostname: 28.30.0.0
hostname: 28.30.0.0
hostname: 28.30.0.0
hostname: 28.30.0.0
hostname: 16.2.0.0
hostname: 16.2.0.0
Voici le code de base:
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <stdio.h>
int main()
{
struct addrinfo* feed_server = NULL;
getaddrinfo("localhost", NULL, NULL, &feed_server);
struct addrinfo *res;
for(res = feed_server; res != NULL; res = res->ai_next)
{
printf("hostname: %s\n", inet_ntoa(*((struct in_addr*)(res->ai_addr))));
}
return 0;
}
En plus de la réponse exacte, vous ne devriez pas oublier de
freeaddrinfo(feed_server);
OriginalL'auteur | 2011-04-22
Vous devez vous connecter pour publier un commentaire.
res->ai_addr
est de typestruct sockaddr*
, passtruct in_addr*
.Vous avez besoin de faire quelque chose comme ceci:
inet_ntoa
est obsolète et nécessite laid adresse-famille-spécifique (c'est à dire IPv4 spécifique) et le code à utiliser. Au lieu de cela, utilisergetnameinfo
avecNI_NUMERICHOST
pour convertir l'adresse de retour d'une chaîne de caractères sous forme numérique.Eh bien, si vous purement utiliser
getaddrinfo
etgetnameinfo
, vous n'avez pas de soins si vous avez de nouveau une adresse IPv6. Tout fonctionne, tout simplement. C'est toute la beauté de celui-ci.Est-il "fonctionne" même si vous utilisez seulement sockaddr_in et pas sockaddr_in6?
Si vous utilisez correctement l'abstraction
getaddrinfo
etgetnameinfo
fournir, vous n'aurez jamais à écrirestruct sockaddr_in
oustruct sockaddr_in6
dans votre code.Vous devez tenir compte du fait que getaddrinfo pourrait adresses de retour qui ne sont pas en IPv4. Casting pour un sockaddr_in inconditionnellement va donner des résultats incorrects dans certaines circonstances.
OriginalL'auteur John Ledbetter
Vous devez utiliser des astuces pour call of
getaddrinfo
. Parce que pour résoudre "localhost" ou tout/etc/hosts
enregistrementhints.af_family
doit être mis àAF_INET
.OriginalL'auteur Sergiy Zaschipas
Il y a deux problèmes avec le code d'origine:
Une chose en général, je vois au moins sur les systèmes Linux, c'est que getaddrinfo pour localhost renvoie généralement à l'IPv6 adresse ::1 en premier.
À partir de l'adresse imprimée que je peux vous dire en cours d'exécution sur un système d'exploitation qui comprend la sockaddrs longueur de la struct. Par exemple, la définition de la struct sockaddr sur OS X est:
Pour les deux struct sockaddr_in et sockaddr_in6 le très prochain membre après sa_family est le port qui est toujours à deux octets. Ainsi, lorsque vous lancez l'une de ces structures à une struct in_addr, vous obtiendrez une adresse qui est sa_len.sa_family.0.0 (en supposant que vous ne fournissez pas un port de getaddrinfo - si vous fournissez un port 0,0 sera remplacé par les ports valeurs d'octets).
Donc gettaddr info est de retour à vous deux adresses IPv6:
28.30.0.0 - sizeof struct sockaddr_in6 = 28 et af_family = 30
et deux adresses IPv4:
16.2.0.0 - sizeof struct sockaddr_in = 16 et af_family = 2
Pour ce faire correctement, vous pourriez faire ce que l'autre réponse, a déclaré et l'utilisation getnameinfo. Cependant, l'utilisation de inet_ntop (pas inet_ntoa) peut être tout aussi bonne.
``
OriginalL'auteur Matt