如何清除System.Net客户端DNS缓存?

39
我使用.NET WebRequest同时更改我的HOSTS文件。我发现System.Net并没有遵守这些更改 - 我该如何让它遵守呢?
我有多个服务器在单一主机名(example.com)后面进行负载平衡。我想要分别针对其中的几台服务器,所以我的程序将在向example.com发送请求之前,在我的HOSTS文件中硬编码特定于机器的IP地址:
163.56.0.34  example.com

对于第一台服务器和第一个请求,这很好。然后我的程序再次更改HOSTS文件:

163.56.0.48  example.com
我创建了一个新的HttpWebRequest。 当我发送请求时,通过 NETMON 观察到它会转到第一个 IP 地址 (163.56.0.34) 而不是预期的第二个 IP 地址。
使用断点和调试跟踪,我已经验证每次 HOSTS 文件中都写入了正确的值。当我尝试从浏览器或其他程序访问 example.com 时,它确实遵循 HOSTS 文件并转到第二个 IP 地址。
使用 NETMON 验证请求直接发送到显示的 IP 地址,没有 HTTP 代理。
由于其他一切都尊重更改后的 HOSTS 文件,我强烈怀疑 System.Net 基础结构缓存了 example.com 的 DNS 主机-IP 关联。然而,我找不到有关此缓存的参考,并且不知道如何清除它或关闭它。
我希望得到处理缓存的指示,对于可能导致这些症状的其他原因的建议,或者有用的其他诊断步骤的建议。
4个回答

49

我最终从MSDN挖掘出了这个晦涩的命令,可以解决这个问题:

ServicePointManager.DnsRefreshTimeout = 0;

我发现在撤销之前尝试的所有奇怪事情时,还需要一个与上面设置一起使用的设置; 就是在请求对象中关闭keep-alive:

request.KeepAlive = false;

3
将KeepAlive设置为false会导致每个请求都进行TCP握手。你可以通过管理ServicePoint.ConnectionLeaseTimeout来达到一个折衷的方案,这样你就可以重用一些连接,同时在重新连接时仍然检查DNS是否有可能发生变化。 - ScottS
对于那些使用WCF ClientBase<T>而不是HttpWebRequest或WebClient来处理SOAP服务的人来说,这是一个很好的选择。 - KevinBui

14

虽然回答有些晚,但我发现这个解决方案比被接受的答案更好。在我的情况下,我正在测试SQL连接,由于没有request.KeepAlive可以设置,因此无法应用现有的答案。

这个页面是Brian Mancini("derp turkey")清除DNS缓存时的冒险经历的详细说明。完全赞成他的做法,我只是在这里添加他的解决方案:

public class DnsUtils  
{        
    [DllImport("dnsapi.dll", EntryPoint="DnsFlushResolverCache")]
    static extern UInt32 DnsFlushResolverCache();

    [DllImport("dnsapi.dll", EntryPoint = "DnsFlushResolverCacheEntry_A")]
    public static extern int DnsFlushResolverCacheEntry(string hostName);

    public static void FlushCache()
    {
        DnsFlushResolverCache();
    }

    public static void FlushCache(string hostName)
    {
        DnsFlushResolverCacheEntry(hostName);
    }
}

非常感谢,伙计! - wan_keen
哇,当我已经失去所有希望时,这个对我起作用了,谢谢! - Daniele

5

如果您想保持 DnsRefreshTimeout > 0,则可以通过调用以下方法来更新缓存:

System.Net.Dns.GetHostEntry("example.com");

根据Ian的回答中引用的Brian Mancini(“derp turkey”)博客页面,GetHostEntry()使用缓存。因此,这不是确保清除该主机名的缓存条目的方法。 - jk7

3
您可以使用 System.Diagnostics.Process 启动 ipconfig /flushdns。

7
我尝试了那个方法,但它只清空了计算机的DNS缓存,而没有清空System.Net进程级别的缓存。 - Bruce
1
你可以重新启动服务器的建议。 - Wiktor Zychla
哈哈 - 重新安装Windows! - Boppity Bop

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接