当我为 localhost 执行 getaddrinfo 时,我没有收到 127.0.0.1
我仍在学习套接字,不清楚为什么这不打印出 127.0.0.1。即使我用 127.0.0.1 替换 localhost 这个词,我也会收到一些其他 ip,我猜是我的路由器之类的。我一直认为这应该返回 127.0.0.1。这是我收到的输出:
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
这是基本代码:
#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;
}
I am still learning sockets and am unclear why this doesn't print out 127.0.0.1. Even if I replace the word localhost with 127.0.0.1 I receive some other ip's which I guess are my router or something. I always thought this should return 127.0.0.1. Here's the output I receive:
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
Here is the basic code:
#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;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
原始代码有两个问题:
我通常至少在 Linux 系统上看到的一件事是 localhost 的 getaddrinfo 通常首先返回 IPv6 ::1 地址。
从打印的地址我可以知道您正在运行一个在结构中包含 sockaddrs 长度的操作系统。例如,OS X 上 struct sockaddr 的定义是:
对于 struct sockaddr_in 和 sockaddr_in6,sa_family 之后的下一个成员是端口,它始终是两个字节。因此,当您将这些结构中的任何一个转换为结构 in_addr 时,您将得到一个地址 sa_len.sa_family.0.0 (假设您没有提供 getaddrinfo 的端口 - 如果您提供端口,则 0.0 将被替换为端口字节值)。
所以 gettaddr info 返回两个 IPv6 地址:
28.30.0.0 - sizeof struct sockaddr_in6 = 28 和 af_family = 30
和两个 IPv4 地址:
16.2.0.0 - sizeof struct sockaddr_in = 16 和 af_family = 2
要正确执行此操作,您可以执行其他答案所说的操作并使用 getnameinfo。然而,使用 inet_ntop (不是 inet_ntoa)也同样好。
````
There are two problems with the original code:
One thing I typically see at least on Linux systems is that getaddrinfo for localhost usually returns the IPv6 ::1 address first.
From the addresses being printed I can tell you are running on an OS that includes the sockaddrs length in the struct. For example the definition of struct sockaddr on OS X is:
For both struct sockaddr_in and sockaddr_in6 the very next member after sa_family is the port which is always two bytes. So when you cast either of these structs to a struct in_addr you will get an address that is sa_len.sa_family.0.0 (assuming you don't provide a port to getaddrinfo - if you provide a port the 0.0 will be replaced with the ports byte values).
So gettaddr info is returning you two IPv6 addresses:
28.30.0.0 - sizeof struct sockaddr_in6 = 28 and af_family = 30
and two IPv4 addresses:
16.2.0.0 - sizeof struct sockaddr_in = 16 and af_family = 2
To do this properly you could do what the other answer said and use getnameinfo. However using inet_ntop (not inet_ntoa) can be equally as good.
```
res->ai_addr
的类型为struct sockaddr*
,而不是struct in_addr*
。你需要做这样的事情:
res->ai_addr
is of typestruct sockaddr*
, notstruct in_addr*
.You need to do something like this:
您应该使用
getaddrinfo
调用的提示。因为要解析“localhost”或任何/etc/hosts
记录,hints.af_family
必须设置为AF_INET
。You should use hints for call of
getaddrinfo
. Because to resolve "localhost" or any/etc/hosts
recordhints.af_family
must be set toAF_INET
.