0

我刚刚写了这个片段:

#include <iostream>
#include <netdb.h>
#include <arpa/inet.h>

int main(void)
{
    sockaddr_in self;
    hostent *he;
    char local[HOST_NAME_MAX];
    gethostname(local, sizeof(local));
    he = gethostbyname(local);

    if (he)
    {
        std::cout << "Addresses: " << std::endl;
        unsigned int i = 0;
        while(he->h_addr_list[i] != NULL)
        {
            std::cout << "\t" << i << " --> ";
            memcpy(&self.sin_addr, he->h_addr_list[i], he->h_length);
            std::cout << self.sin_addr.s_addr;
            std::cout << " ( " << inet_ntoa( *( struct in_addr*)( he-> h_addr_list[i])) << " )" << std::endl;
            i++;
        }
    }
    else
        std::cout << "gethostname failed" << std::endl;
}

当我在示例主机上运行它时,我会得到类似这样的东西(不过我在这里编了这些地址):

地址:0 --> 1307150150 ( 10.23.215.61 )

而如果我运行,ifconfig我会得到更多的输出,特别是上面的地址只对应于第一个显示的界面,而ifconfig在这些界面之前至少还有两个eth0。怎么会?我本来希望这会贯穿该主机中所有可能的网络地址...

在下面的答案之后,我做了以下(使用getaddrinfo):

int main(void)
{
    struct addrinfo *result;
    struct addrinfo *res;
    int error;

    char local[HOST_NAME_MAX];
    gethostname(local, sizeof(local));

    error = getaddrinfo(local, NULL, NULL, &result);
    if (error != 0)
    {
        fprintf(stderr, "error in getaddrinfo: %s\n", gai_strerror(error));
        return 1;
    }

    for (res = result; res != NULL; res = res->ai_next)
    {
        struct in_addr addr;
        addr.s_addr = ((struct sockaddr_in *)(res->ai_addr))->sin_addr.s_addr;
        std::cout << addr.s_addr
                  << " ("
                  << inet_ntoa(addr)
                  << " )"
                  << std::endl;
    }

    freeaddrinfo(result);
}

我现在得到与以前相同的输出......除了重复“正确”的次数。(即从 ifconfig 我看到三个接口,我大概可以从多播中发送,我得到第一个重复三次的 inet 地址作为上面的输出。

4

1 回答 1

1

该函数gethostname返回主机配置的名称。您可以使用您选择的任何名称自由配置您的计算机。

该函数gethostbyname为您的操作系统执行“正常”名称解析过程。通常,它会首先查看/etc/hosts您的 DNS 解析器,如果查询失败。

gethostbyname返回您配置的所有 IP 地址,您必须将它们放入您的/etc/hosts文件中或要求您的 DNS 管理员更新您的服务器。

顺便说一句,gethostbyname不推荐使用getaddrinfo

于 2012-12-24T07:01:50.700 回答