Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/155.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/62.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 获取了本地主机名,在windows上工作,但在Linux上不工作_C++_C_Linux_Windows_Getaddrinfo - Fatal编程技术网

C++ 获取了本地主机名,在windows上工作,但在Linux上不工作

C++ 获取了本地主机名,在windows上工作,但在Linux上不工作,c++,c,linux,windows,getaddrinfo,C++,C,Linux,Windows,Getaddrinfo,我写了一个程序来获取本地主机名。如果不明显,我的意思是获取本地计算机的主机名,类似于gethostname方法,而不是获取字符串localhost 我使用getaddrinfo和NULL作为主机名,然后使用第一个地址调用getnameinfo 它可以在windows机器上完美地工作,并为我提供标准主机名,但在Linux中,它无法为我提供本地主机名,并为IPv6提供:,或为IPv4提供0.0.0 请注意,我在getaddrinfo中使用了AI_PASSIVE标志,这意味着它给我的地址不超过两个 在

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

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

它可以在windows机器上完美地工作,并为我提供标准主机名,但在Linux中,它无法为我提供本地主机名,并为IPv6提供
,或为IPv4提供
0.0.0

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

getnameinfo
中,如果我使用
NI\u NAMEREQD
它将失败

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

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

谢谢你的帮助

这是我的代码:(跨平台,windows和Linux,只需复制和过去) 您可以编译和运行这两个程序,并看到它们的区别

#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;
}
#包括
#ifdef WIN32
#ifdef UNICODE
#undef UNICODE/*不需要UNICODE,以保持代码兼容性*/
#恩迪夫
#包括
#pragma注释(lib,“ws2_32.lib”)
类初始化器{
公众:
cwsai初始化器(){
WSADATA数据;
WSAStartup(MAKEWORD(2,2)和数据);
}
~CWSAInitializer(){
WSACleanup();
}
}自动初始化;
#否则
#包括
#包括
#包括
#恩迪夫
const char*get_主机名(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);
如果(res){
返回NULL;
}
返回buff;
}
int main()
{
炭温度[100];
addrinfo*ai,提示;
memset(&hints,0,sizeof(hints));
hits.ai_family=AF_unsec;
hits.ai_socktype=SOCK_流;
hits.ai_flags=ai_NUMERICSERV;
hits.ai_flags |=ai_被动;
int res=getaddrinfo(NULL,“0”&提示和ai);
如果(res){
std::cerr
getaddrinfo()
返回
struct addrinfo
节点的列表头

使用
struct addrinfo
的a成员
ai_next
遍历此列表,以查找机器所有接口的地址

要接收除通配符地址以外的任何其他地址,请在传递的提示中指定
AI_PASSIVE
标志


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

  • gethostname()返回的主机名(“主机名”)
    是主机的一个属性。它在主机上配置,不保存在任何外部数据库中。每个定义的此主机名未链接到可能的接口地址解析到的任何名称。主机名可能但是可以配置以匹配该名称一个地址(机器接口)解析为

  • 一台计算机可能提供多个接口。每个接口的地址都应解析为不同的名称,而这些名称也可能与
    gethostname()
    返回的名称不同(请参见上文1)。这适用于所有类型的接口,包括IPv4和IPv6。还有虚拟通配符地址(
    0.0.0
    ,适用于IPv4),它允许程序绑定并侦听计算机提供的所有接口(此处键入的IPv4)。通配符地址有名称

  • 从1.和2.中得出的结论是:没有名称“…类似于[returned by]gethostname()”!

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

    使用
    struct addrinfo
    的a成员
    ai_next
    遍历此列表,以查找机器所有接口的地址

    要接收除通配符地址以外的任何其他地址,请在传递的提示中指定
    AI_PASSIVE
    标志


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

  • gethostname()返回的主机名(“主机名”)
    是主机的一个属性。它在主机上配置,不保存在任何外部数据库中。每个定义的此主机名未链接到可能的接口地址解析到的任何名称。主机名可能但是可以配置以匹配该名称一个地址(机器接口)解析为

  • 一台计算机可能提供多个接口。每个接口的地址都应解析为不同的名称,而这些名称也可能与
    gethostname()
    返回的名称不同(请参见上文1)。这适用于所有类型的接口,包括IPv4和IPv6。还有虚拟通配符地址(
    0.0.0
    ,适用于IPv4),它允许程序绑定并侦听计算机提供的所有接口(此处键入的IPv4)。通配符地址有名称


  • 从1.和2.得出的结论是:没有名称“…像[returned by]gethostname()一样,而是规范的。”!

    如果您只想要本地主机名,为什么不使用INADDR\u环回?我不想要本地主机接口。服务器正在外部侦听,我想知道我当前正在侦听哪个主机名。如果客户端尝试连接到::或0.0.0.0,它将不会连接。如果您只想要本地主机名,为什么不使用INADDR