web-dev-qa-db-ja.com

System.NetクライアントのDNSキャッシュをクリアするにはどうすればよいですか?

HOSTSファイルの変更中に.NET WebRequestを使用しています。 System.Netがこれらの変更を尊重しないことを確認しています。どのようにすればそれを実現できますか?

単一のホスト名の背後に負荷分散された複数のサーバーがあります。たとえば、「example.com」としましょう。それらのいくつかを個別にターゲットにしたいので、私のプログラムは、examples.comにリクエストを送信する前に、HOSTSファイルにマシン固有のIPアドレスをハードコードします。

163.56.0.34  example.com

最初のサーバーと最初のリクエストでは、これは正常に機能します。次に、私のプログラムはHOSTSファイルを再度変更します。

163.56.0.48  example.com

そして、新しいHttpWebRequestを作成します。これを送信すると、予想される2番目のIPアドレスではなく、最初のIPアドレス(163.56.0.34)に送信されることがNETMONで確認できます。

ブレークポイントとデバッグトレースを使用して、正しい値が毎回HOSTSファイルに書き込まれることを確認しました。ブラウザまたは他のプログラムからexample.comにアクセスしようとすると、HOSTSファイルが優先され、2番目のIPアドレスに移動します。

NETMONを使用して、表示されているIPアドレスにリクエストが直接送信されることを確認しました。 HTTPプロキシはありません。

他のすべてが変更されたHOSTSファイルを尊重しているので、System.Netインフラストラクチャがexample.comのDNSホストとIPの関連付けをキャッシュしていると強く思います。しかし、私はこのキャッシングへの参照を見つけることができず、それをフラッシュしたりオフにしたりする方法を知りません。

キャッシュの取り扱い手順、他にこれらの症状を引き起こしている可能性のある提案、または役立つと思われる他の診断手順を歓迎します。

33
Bruce

最後に、これを修正するMSDNのあいまいなコマンドを掘り下げました。

ServicePointManager.DnsRefreshTimeout = 0;

以前に試した奇妙なことをすべて解くと、上記のものと一緒に必要な設定がもう1つ見つかりました。リクエストオブジェクトで、キープアライブをオフにします。

request.KeepAlive = false;
41
Bruce

確かに遅い答えですが、この解決策は受け入れられた答えよりもうまく機能することがわかりました。私のシナリオではSQL接続をテストしていますが、request.KeepAliveを設定する必要がないため、既存の回答を適用できませんでした。

このページ by 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);
    }
}
6
Ian

DnsRefreshTimeout> 0を維持したい場合は、以下を呼び出してキャッシュを更新できます。

System.Net.Dns.GetHostEntry("example.com");
5
Lee Gunn

system.Diagnostics.Processを使用してipconfig/flushdnsを起動できます

3
AMH