如果我执行命令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函数的返回值,因此如果它们“失败”,并且它们的结果因此毫无意义,那么你就没有检测到它。
我强烈怀疑这是这种情况,所以你基本上只是观察废话(可能是在调试版本中将完全未初始化的sockaddr_in
传递给getnameinfo
的结果)。
如果没有错误发生,InetPton函数返回值1,pAddrBuf参数指向的缓冲区包含网络字节顺序的二进制数字IP地址。
如果pAddrBuf参数指向的字符串不是有效的IPv4点分十进制字符串或有效的IPv6地址字符串,则InetPton函数返回值0。否则,返回值-1,并且可以通过调用WSAGetLastError获取扩展错误信息来检索特定错误代码。
(Qazxswpoi)
默认情况下,未初始化的变量在VS中的调试中获得此值。
它解析了204.204.204.204,因为它结合了:(1)未初始化的,(2)空socket_address
,以及(3)Debug-configuration [Visual Studio C ++]: - >未初始化的ip_address
只有一个值(204.204。 204.204偶然因为Debug-configuration), - > socket_address
失败(因为空InetPtonA
),因此 - > ip_address
没有改变。
用0初始化socket_address
:
socket_address
&它不再解决204.204.204.204。它说204是Debug-configuration中未初始化变量的默认值,但我不会指望该值。在没有初始化的Release-configuration中,它只是一个垃圾:
struct sockaddr_in socket_address; memset(&socket_address, 0, sizeof(sockaddr_in));
--
要正确使用,请使用正确的get_computer_name
。 ip_address
的第二个参数应包含“指向以NULL结尾的字符串的指针,该字符串包含要转换为数字二进制形式的IP地址的文本表示形式。” [MSDN]。像这样的东西:
netPtonA