首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >获得本地主机名,在windows上工作,但在Linux中没有。

获得本地主机名,在windows上工作,但在Linux中没有。
EN

Stack Overflow用户
提问于 2013-12-02 16:43:15
回答 1查看 1.1K关注 0票数 1

我写了一个程序来获取本地主机名。如果不明显,我的意思是获取本地机器的主机名,类似于gethostname方法,而不是获取字符串localhost

我使用getaddrinfoNULL作为主机名,然后用第一个地址调用getnameinfo

它在windows机器上运行得很好,并给出了规范的主机名,但在Linux中,它没有给我本地主机名,并给我IPv6的::或IPv4的0.0.0.0

注意,我在getaddrinfo中使用了getaddrinfo标志,这意味着它给我的地址不超过两个。

getnameinfo中,如果我使用NI_NAMEREQD,它将失败。

我这么做是因为我有一个服务器,有时我想监听所有的接口,有时我想听特定的接口,我已经拥有了addrinfo,如果可能的话,我只想从它获得主机名。

我如何使它在Linux上工作呢?我错过了什么吗?

谢谢你的帮助。

下面是我的代码:(跨平台、windows和Linux,只需复制和过去)您可以编译和运行这两种代码,并查看它们之间的区别。

代码语言:javascript
复制
#include <iostream> 

#ifdef WIN32

#ifdef UNICODE
#undef UNICODE /* don't want Unicode, to keep code compatibility */
#endif

#include <WS2tcpip.h>
#pragma comment(lib, "ws2_32.lib")
class CWSAInitializer{
public:
    CWSAInitializer(){
        WSADATA data;
        WSAStartup(MAKEWORD(2,2),&data);
    }
    ~CWSAInitializer(){
        WSACleanup();
    }
}autoInit;

#else
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#endif

const char* get_hostname(struct addrinfo* info, char buff[], int buff_len)
{
    int addrlen = (int)info->ai_addrlen;
    int res = getnameinfo(info->ai_addr, addrlen, buff, buff_len, NULL, 0, 0);
    if(res){
        return NULL;
    }
    return buff;
}

int main () 
{
    char temp[100];
    addrinfo *ai,hints;
    memset(&hints,0,sizeof(hints));
    hints.ai_family = AF_UNSPEC;
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_flags = AI_NUMERICSERV;
    hints.ai_flags |= AI_PASSIVE;

    int res = getaddrinfo(NULL, "0", &hints, &ai); 
    if(res){
        std::cerr<<gai_strerror(res)<<std::endl;
        return -1;
    }
    std::cout<< get_hostname(ai,temp,100)<<std::endl;
    freeaddrinfo(ai);

    return 0;
}

编辑

  1. 服务器也应该接受来自其他机器的客户端,所以它不能报告侦听::0.0.0.0
  2. 我知道我可以这样修补它:

if(std::string("::") == hostname || std::string("0.0.0.0") == hostname) gethostname(hostname,100)

  1. 因此,我不想得到localhost,除非地址是127.0.0.1::1
EN

回答 1

Stack Overflow用户

发布于 2013-12-02 17:15:42

getaddrinfo()返回struct addrinfo节点列表的头。

使用struct addrinfo的一个成员ai_next来查找机器所有接口的地址。

若要接收除通配符地址以外的其他内容,请执行而不是,请在传递的提示中指定AI_PASSIVE标志。

更新给机器的各种名称和/或其接口地址:

  1. gethostname()返回主机名(“主机名”)是主机的一个属性。它是在主机上配置的,而不是保存在任何外部数据库中。每个定义的主机名没有将链接到可能的接口地址解析的任何名称。但是,主机名可能是,但是配置了以匹配地址(计算机接口)解析的one解析的名称。
  2. 机器提供的接口可能不止一个。这些接口的每个地址都应该解析为不同的名称,这反过来也可能与gethostname()返回的名称不同(参见上文1 )。这适用于所有类型的接口,包括IPv4和IPv6。这里还有虚拟通配符地址(0.0.0.0for IPv4),它允许程序绑定和侦听计算机提供的all接口(在这里输入的IPv4)。通配符-adresse有,没有名称。

第1和第2节的结论是:没有名称“.就像gethostname()返回的那样,但是是规范的”!

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/20333364

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档