Linux getaddrinfo获得本机ip地址为何127.0.1.1?
通过gethostname + getaddrinfo , 得到本机ip地址为127.0.1.1 , 而非127.0.0.1. 为何?
源代码
int main(int argc, const char **argv)
{
int ret;
char host_name[128] = {0};
struct addrinfo *res, *cur;
struct sockaddr_in *addr;
if (gethostname(host_name, sizeof(host_name)) < 0)
{
printf("gethostname error\n");
return -1;
}
ret = getaddrinfo(host_name, NULL, NULL, &res);
if (ret != 0)
{
printf("Error: error in getaddrinfo on hostname: %s\n", gai_strerror(ret));
return -1;
}
for(cur = res; cur != NULL; cur = cur->ai_next)
{
if(cur->ai_family == AF_INET)
{
addr = (struct sockaddr_in*)cur->ai_addr;
printf("local ip:%s\n", inet_ntoa(addr->sin_addr));
}
}
freeaddrinfo(res);
return 0;
}
运行输出
local ip:127.0.1.1
local ip:127.0.1.1
local ip:127.0.1.1
问题
- 为何是3行?
- 为何得到ip地址127.0.1.1?
对于问题1, 查看ip网卡配置信息, 发现有3个网卡配置信息
$ ifconfig -a
对于问题2, 查看/etc/hosts. 可以看到对应与主机名martin-ThinkPad-T480, ip地址是127.0.1.1. 而martin-ThinkPad-T480 正是通过gethostname得到.
这也是在告诉我们, getaddrinfo取得的不是本地网卡ip地址, 而是hosts文件的配置name的ip地址.
2种解决办法:
- 修改hosts文件, 主机名对应ip地址;
- 不用gethostname取得主机名, 而是直接用localhost;
$ vim /etc/hosts
127.0.0.1 localhost
127.0.1.1 martin-ThinkPad-T480
# The following lines are desirable for IPv6 capable hosts
::1 ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
总结
- getaddrinfo得到的IP地址不是真实网卡ip地址, 而是/etc/hosts配置的用户名对应ip地址, 因此不适合用于动态取得本机网卡ip地址, 更适合于本地回环测试;