2011-09-01 32 views
24

Używam .NET WebRequest podczas zmiany mojego pliku HOSTS. Obserwuję, że System.Net nie honoruje tych zmian - jak mogę to zrobić?Jak wyczyścić pamięć podręczną DNS klienta System.Net?

Mam liczbę serwerów z równoważeniem obciążenia za pomocą pojedynczego hosta, powiedzmy „example.com”. Chcę kierować kilka z nich z osobna, więc mój program będzie ciężko kod adres IP maszyny specyficzne w moich pliku HOSTS przed wysłaniem żądania example.com:

163.56.0.34 example.com 

Dla pierwszego serwera i pierwsze żądanie, to działa dobrze. Wtedy mój program zmienia pliku hosts ponownie:

163.56.0.48 example.com 

I utworzyć nowy HttpWebRequest. Kiedy wyślę to, mogę zaobserwować w NETMONIE, że przechodzi do pierwszego adresu IP (163.56.0.34) zamiast oczekiwanego drugiego.

Korzystanie punkty przerwania i ślady debugowania, I zostały zweryfikowane, że poprawna wartość nie sposób zapisany w pliku hosts za każdym razem. Kiedy próbuję uzyskać dostęp do example.com z przeglądarki lub innego programu, honoruje on plik HOSTS i przechodzi do drugiego adresu IP.

Korzystanie Netmon I zostały zweryfikowane, że wnioski będą bezpośrednio na adres IP pokazanej; nie ma serwera proxy HTTP.

Ponieważ wszystko inne jest uhonorowanie plik HOSTS zmienione, ja podejrzewam, że infrastruktura System.Net jest buforowane stowarzyszenie IP hosta DNS dla example.com. Jednak nie mogę znaleźć odniesienia do tego buforowania i nie wiem, jak go opróżnić lub wyłączyć.

chciałbym powitać instrukcje do czynienia z pamięci podręcznej, propozycje co jeszcze może być przyczyną tych objawów lub innych proponowanych czynności diagnostycznych, które mogą być użyteczne.

Odpowiedz

37

końcu wykopano niejasne polecenie z MSDN, która rozwiązuje ten:

ServicePointManager.DnsRefreshTimeout = 0; 

Jak odwija ​​wszystkie dziwne rzeczy ja” Próbowałem wcześniej, odkryłem jedno inne ustawienie, które potrzebuję wraz z powyższym; na obiekcie żądania, wyłącz keep-alive:

request.KeepAlive = false; 
+1

Ustawienie KeepAlive na false spowoduje uzgadnianie protokołu TCP dla każdego żądania. Możesz osiągnąć średni poziom, zarządzając ServicePoint.ConnectionLeaseTimeout, aby ponownie wykorzystać niektóre połączenia, nadal sprawdzając DNS pod kątem możliwych zmian po ponownym połączeniu. – ScottS

3

można użyć System.Diagnostics.Process uruchomić ipconfig/flushdns

+4

Próbowałem tego i to nie działa - to czyści pamięć podręczną DNS urządzenia, ale nie proces poziomu cache System.Net użytkownika. – Bruce

5

Jeśli chcesz zachować DnsRefreshTimeout> 0 wtedy można zaktualizować cache poprzez wykonanie połączenia do:

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

Późne odpowiedzi na upewnij się, ale stwierdziłem, że to rozwiązanie działa lepiej niż zaakceptowana odpowiedź. W moim scenariuszu testuję połączenia SQL i nie mogłem zastosować istniejącej odpowiedzi, ponieważ nie mam do ustawienia request.KeepAlive.

This page Brian Mancini ("derp turkey") opisuje swoją przygodę podczas czyszczenia pamięci podręcznej DNS. Pełne rekwizyty do niego, po prostu dodając swoje rozwiązanie tutaj:

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); 
    } 
} 
Powiązane problemy