将 DNS 名称解析为 IP 地址...我应该从众多 IP 中选择哪一个?
Resolving a DNS name to an IPAddress... Which one of the many IPs should I pick?
将主机名解析为 IP 地址很简单:
foreach (var hostName in new [] { "github.com", "microsoft.com", "google.com", "whosebug.com" })
{
var ipAddresses = Dns.GetHostAddresses(hostName);
Console.WriteLine($"=== {hostName}");
Console.WriteLine(string.Join(Environment.NewLine, ipAddresses.Select(ip => ip.ToString())));
Console.WriteLine();
}
如果我现在想 select 一个 IP 地址 来建立连接(并记录那个确切的 IP 地址),我将如何 select是吗?
并发症:
- 可以有多个IP地址。
- 可以有多个地址族(IPv4 与 IPv6)。
- 可能会返回 IPv6 地址,但系统可能不支持 IPv6。
是否有公认或推荐的选择方式?
这将 select 每个主机的第一个 IP 地址。
foreach (var hostName in new[] { "github.com", "microsoft.com", "google.com", "whosebug.com" })
{
var ipAddresses = Dns.GetHostAddresses(hostName);
Console.WriteLine($"=== {hostName}");
Console.WriteLine(ipAddresses.FirstOrDefault());
Console.WriteLine();
}
在我的研究过程中,我发现了以下相关方面:
- 一些来源建议按照解析器和 OS 返回的顺序使用 IP 地址。
- 通过这种方式,可以开发出基于客户端 IP 的负载平衡的智能 DNS 解决方案,但也允许客户端故障转移到更远程的 IP。
- 如果不需要冗余,客户端可以只选择第一个IP。如果先返回 IPv6 地址但不支持 IPv6,这可能很危险。网络资源说许多不成熟的客户使用这种方法。
- 客户端可以尝试这些地址以实现冗余。超时管理在这里变得更加重要。显然,浏览器会这样做。
- 根据是否支持 IPv4 and/or IPv6,过滤掉不支持的地址族的地址是有意义的。
- Patrick Mevzek 建议在支持的地方优先使用 IPv6,以帮助采用 IPv6。
- 有时除非尝试连接,否则无法确定 IPv6 是否可用。为了最大限度地减少连接延迟,应用程序可以并行使用 IPv4 和 IPv6 进行连接。这叫做Happy Eyeballs.
.NET Framework 在 Socket.Connect(string hostName, int port)
中实现了以下算法:它解析所有 IP 地址,过滤掉不支持的地址系列,并尝试按顺序连接到它们。这个算法对我来说似乎是最好的。 TcpClient.Connect(string hostName, int port)
做了一些我无法完全理解的类似事情。
将主机名解析为 IP 地址很简单:
foreach (var hostName in new [] { "github.com", "microsoft.com", "google.com", "whosebug.com" })
{
var ipAddresses = Dns.GetHostAddresses(hostName);
Console.WriteLine($"=== {hostName}");
Console.WriteLine(string.Join(Environment.NewLine, ipAddresses.Select(ip => ip.ToString())));
Console.WriteLine();
}
如果我现在想 select 一个 IP 地址 来建立连接(并记录那个确切的 IP 地址),我将如何 select是吗?
并发症:
- 可以有多个IP地址。
- 可以有多个地址族(IPv4 与 IPv6)。
- 可能会返回 IPv6 地址,但系统可能不支持 IPv6。
是否有公认或推荐的选择方式?
这将 select 每个主机的第一个 IP 地址。
foreach (var hostName in new[] { "github.com", "microsoft.com", "google.com", "whosebug.com" })
{
var ipAddresses = Dns.GetHostAddresses(hostName);
Console.WriteLine($"=== {hostName}");
Console.WriteLine(ipAddresses.FirstOrDefault());
Console.WriteLine();
}
在我的研究过程中,我发现了以下相关方面:
- 一些来源建议按照解析器和 OS 返回的顺序使用 IP 地址。
- 通过这种方式,可以开发出基于客户端 IP 的负载平衡的智能 DNS 解决方案,但也允许客户端故障转移到更远程的 IP。
- 如果不需要冗余,客户端可以只选择第一个IP。如果先返回 IPv6 地址但不支持 IPv6,这可能很危险。网络资源说许多不成熟的客户使用这种方法。
- 客户端可以尝试这些地址以实现冗余。超时管理在这里变得更加重要。显然,浏览器会这样做。
- 根据是否支持 IPv4 and/or IPv6,过滤掉不支持的地址族的地址是有意义的。
- Patrick Mevzek 建议在支持的地方优先使用 IPv6,以帮助采用 IPv6。
- 有时除非尝试连接,否则无法确定 IPv6 是否可用。为了最大限度地减少连接延迟,应用程序可以并行使用 IPv4 和 IPv6 进行连接。这叫做Happy Eyeballs.
.NET Framework 在 Socket.Connect(string hostName, int port)
中实现了以下算法:它解析所有 IP 地址,过滤掉不支持的地址系列,并尝试按顺序连接到它们。这个算法对我来说似乎是最好的。 TcpClient.Connect(string hostName, int port)
做了一些我无法完全理解的类似事情。