由于我在上一个问题上没有答案,我会改写它.
在使用PC名称(NetBIOS名称)执行gethostbyname()时,使用了什么顺序的IP地址(如果IP地址绑定到一个接口)?
我有这个代码:
#include <iostream>
#include <winsock.h>
#pragma comment(lib, "Ws2_32.lib")
int main()
{
char hostname[255];
struct hostent *he;
struct in_addr **addr_list;
WSAData data;
WSAStartup(MAKEWORD(2, 2), &data);
gethostname(hostname, 255);
std::cout << "Host name: " << hostname << std::endl;
if ((he = gethostbyname(hostname)) == NULL) {
std::cout << "gethostbyname error" << std::endl;
} else {
std::cout << "IP addresses: " << std::endl;
addr_list = (struct in_addr **)he->h_addr_list;
for(int i = 0; addr_list[i] != NULL; i++) {
std::cout << inet_ntoa(*addr_list[i]) << std::endl;
}
}
std::cin.get();
}
它在Windows Server 2012和Windows Server 2008 / Windows 7上给出了不同的结果.在使用Windows 7的家用PC上,使用了升序:
Host name: SplattWin
IP addresses:
192.168.1.140
192.168.3.1
192.168.3.2
192.168.3.3
192.168.3.4
但是,在Windows Server 2012上,它按降序提供IP地址:
Host name: WinServ
IP addresses:
1.1.1.4
1.1.1.3
1.1.1.2
1.1.1.1
有什么方法可以重新排序吗?我添加这些IP地址时尝试了skipassource标志,但在这种情况下它似乎不起作用.
我有第三方软件,它使用gethostname()后跟gethostbyname()来确定它自己的IP地址(它从列表中首先获得).每次向系统添加新的IP地址时,都需要更改设置和客户端,这真是令人沮丧.
最佳答案 IP的顺序由Windows根据接口优先级等确定.跨越机器边界或Windows版本边界没有标准规则.您必须将输出列表视为随机,并根据您的特定需求自行重新排序IP.例如:
#include <iostream>
#include <vector>
#include <algorithm>
#include <winsock.h>
#pragma comment(lib, "Ws2_32.lib")
bool SortInAddr(const in_addr &a, const in_addr &b)
{
return (a.S_un.S_addr < b.S_un.S_addr);
}
int main()
{
WSAData data;
WSAStartup(MAKEWORD(2, 2), &data);
char hostname[256] = {0};
if (gethostname(hostname, 255) == SOCKET_ERROR)
{
std::cout << "gethostname error: " << WSAGetLastError() << std::endl;
}
else
{
std::cout << "Host name: " << hostname << std::endl;
struct hostent *he = gethostbyname(hostname);
if (he == NULL)
{
std::cout << "gethostbyname error: " << WSAGetLastError() << std::endl;
}
else if (he->h_length != sizeof(in_addr))
{
std::cout << "gethostbyname did not return IPv4 addresses" << std::endl;
}
else
{
std::vector<in_addr> addrs;
struct in_addr **addr_list = (struct in_addr **)(he->h_addr_list);
for(int i = 0; addr_list[i] != NULL; ++i)
{
addrs.push_back(*(addr_list[i]));
}
if (addrs.size() > 1)
{
std::sort(addrs.begin(), addrs.end(), SortInAddr);
}
std::cout << "IPv4 addresses: " << std::endl;
for(std::vector<in_addr>::iterator iter = addrs.begin();
iter != addrs.end();
++iter)
{
std::cout << inet_ntoa(addrs[i]) << std::endl;
}
}
}
WSACleanup();
std::cin.get();
}
话虽这么说,不要使用gethostbyname()(或getaddrinfo())来枚举机器的本地接口.此类功能不适用于此目的.请改用GetAdaptersInfo()或GetAdaptersAddresses().它们专门用于枚举本地接口,它们为您提供有关接口的更多详细信息.