为什么空IP地址将计算机名解析为204.204.204.204?

Why empty IP address resolves computer name as 204.204.204.204?

如果我执行命令 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?

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

我不会太相信这个价值。真正的问题是您没有检查任何 API 函数的 return 值,因此如果它们 "fail",并且它们的结果因此毫无意义,您没有检测到。

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

If no error occurs, the InetPton function returns a value of 1 and the buffer pointed to by the pAddrBuf parameter contains the binary numeric IP address in network byte order.

The InetPton function returns a value of 0 if the pAddrBuf parameter points to a string that is not a valid IPv4 dotted-decimal string or a valid IPv6 address string. Otherwise, a value of -1 is returned, and a specific error code can be retrieved by calling the WSAGetLastError for extended error information.

(ref)

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

它解析 204.204.204.204 是因为以下组合:(1) 未初始化的 socket_address,(2) 空的 ip_address,以及 (3) 调试配置 [Visual Studio C++]: --> Uninitialized 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 是调试配置中未初始化变量的默认值,但我不会指望该值。在没有初始化的Release-configuration中,它只是一个垃圾:

--

get_computer_name得当,用得当ip_addressnetPtonA的第二个参数应该包含"A pointer to the NULL-terminated string that contains the text representation of the IP address to convert to numeric binary form." [MSDN]。类似的东西:

int main()
{
    std::string ip("127.0.0.1"), cn;

    get_computer_name(ip, cn);
    return 0;
}