为啥空 IP 地址将计算机名称解析为 204.204.204.204?

Posted

技术标签:

【中文标题】为啥空 IP 地址将计算机名称解析为 204.204.204.204?【英文标题】:Why empty IP address resolves computer name as 204.204.204.204?为什么空 IP 地址将计算机名称解析为 204.204.204.204? 【发布时间】:2018-10-05 11:22:03 【问题描述】:

如果我执行命令 ping ""tracert "" 它会解析我当前的计算机名称。 但是当我执行下面的代码时,它会将计算机名称解析为“204.204.204.204”

#include <winsock2.h>
#include <ws2tcpip.h>
#include <string>
#include <iostream>

#pragma comment(lib, "Ws2_32.lib")

void get_computer_name(const std::string& ip_address, std::string& computer_name)

    WSADATA wsa_data;
    u_short port = 27015;
    struct sockaddr_in socket_address;
    char service_info[NI_MAXSERV] = ;
    WSAStartup(MAKEWORD(2, 2), &wsa_data);
    socket_address.sin_family = AF_INET;
    const auto error_code = InetPtonA(AF_INET, &ip_address[0], &socket_address.sin_addr.s_addr);

    socket_address.sin_port = htons(port);
    computer_name.resize(NI_MAXHOST);
    getnameinfo((struct sockaddr *) &socket_address,
            sizeof(socket_address),
            &computer_name[0],
            NI_MAXHOST, service_info, NI_MAXSERV, NI_NUMERICSERV);
    WSACleanup();


int main(int argc, wchar_t **argv)

    std::string computer_name;
    get_computer_name("", computer_name);
    std::cout << computer_name << std::endl;
    return 0;

我很好奇为什么是204.204.204.204?

【问题讨论】:

为什么不检查这些函数的返回值?你只是假设他们成功并且他们的结果是有意义的,但这并不一定是真的。 你应该经常检查函数是否成功执行InetPtonA如果发生错误返回1204 对应于 0xCC,对于某些编译和环境,它可能表示调试模式下的内存未初始化。 您需要阅读 each 函数调用的文档,并弄清楚如何正确检查返回值。 if (error_code) 不好。 @Mayur 是我的假设,即您现在在问题中显示的代码不再获得 204.204.204.204 吗?如果是,您不应该对您的问题进行此类更改,因为代码不再反映问题的问题,从而导致答案错误并且“无用” @t.niese 哦,是的。我已经恢复了代码 【参考方案1】:

204 是 0xCC,在某些平台上是未初始化内存的常用占位符。

我不会在这个价值上投入太多。真正的问题是您没有检查任何这些 API 函数的返回值,因此如果它们“失败”并且它们的结果因此毫无意义,那么您没有检测到。

我强烈怀疑这里就是这种情况,所以你基本上只是在观察废话(可能是在调试版本中将完全未初始化的sockaddr_in 传递给getnameinfo 的结果)。

如果没有发生错误,InetPton 函数返回值 1,并且 pAddrBuf 参数指向的缓冲区包含网络字节顺序的二进制数字 IP 地址。

如果 pAddrBuf 参数指向的字符串不是有效的 IPv4 点分十进制字符串或有效的 IPv6 地址字符串,则 InetPton 函数返回值 0。 否则,值 -1返回,并且可以通过调用来检索特定的错误代码 WSAGetLastError 获取扩展错误信息。

(ref)

【讨论】:

【参考方案2】:

未初始化的变量默认在VS中调试得到这个值。

【讨论】:

@drescherjm 这很有帮助 谢谢! :)【参考方案3】:

它解析 204.204.204.204 因为以下组合:(1) 未初始化的 socket_address,(2) 空的 ip_address,以及 (3) 调试配置 [Visual Studio C++]:-- > 未初始化的socket_address 仅具有一个值(由于调试配置,偶然出现204.204.204.204),--> InetPtonA 失败(因为ip_address 为空),并且因此 --> socket_address 没有改变。

用 0 初始化socket_address

struct sockaddr_in socket_address; memset(&socket_address, 0, sizeof(sockaddr_in));

& 它不再解析 204.204.204.204。它说 204 是调试配置中未初始化变量的默认值,但我不会指望该值。在没有初始化的发布配置中,它只是一个垃圾:

--

正确的get_computer_name,使用正确的ip_addressnetPtonA 的第二个参数应包含 “指向以 NULL 结尾的字符串的指针,该字符串包含要转换为数字二进制形式的 IP 地址的文本表示。” [MSDN]。类似的东西:

int main()

    std::string ip("127.0.0.1"), cn;

    get_computer_name(ip, cn);
    return 0;

【讨论】:

ip地址未初始化(用空字符串初始化)是什么意思?你的意思是ip不是127.0.0.1,而是一个空字符串?如果是这样,那么是的,但是 OP 想知道如果 ip 是一个空字符串,为什么结果是 204.204.204.204。如果是关于 cn("");cn; 应该没有任何区别。 @t.niese 我希望现在我能更好地解释自己

以上是关于为啥空 IP 地址将计算机名称解析为 204.204.204.204?的主要内容,如果未能解决你的问题,请参考以下文章

将主机名解析为 IP 地址

正向搜索查询和反向搜索查询的区别是啥?

域名解析成ip地址通过啥服务器

.NET Socket.Connect 将主机名解析为 IP 地址

linux常见错误

为啥要通过IP地址寻址而不通过硬件地址寻址?