Как очистить DNS-кэш клиента System.Net?
Я использую.NET WebRequest при изменении моего файла HOSTS. Я наблюдаю, что System.Net не соблюдает эти изменения - как я могу это сделать?
У меня есть несколько серверов с балансировкой нагрузки за одно имя хоста, скажем, "example.com". Я хочу настроить таргетинг на несколько из них по отдельности, поэтому моя программа жестко закодирует машинный IP-адрес в моем файле HOSTS перед отправкой запроса на example.com:
163.56.0.34 example.com
Для первого сервера и первого запроса это работает нормально. Затем моя программа снова изменяет файл HOSTS:
163.56.0.48 example.com
И я создаю новый HttpWebRequest. Когда я отправляю это сообщение, я могу наблюдать в NETMON, что он идет по первому IP-адресу (163.56.0.34) вместо ожидаемого второго.
Используя точки останова и трассировки отладки, я убедился, что правильное значение записывается в файл HOSTS каждый раз. Когда я пытаюсь получить доступ к example.com из браузера или другой программы, он учитывает файл HOSTS и переходит ко второму IP-адресу.
Используя NETMON, я убедился, что запросы направляются непосредственно на указанный IP-адрес; нет HTTP прокси.
Поскольку все остальное учитывает измененный файл HOSTS, я сильно подозреваю, что инфраструктура System.Net кэшировала ассоциацию DNS хост-IP для example.com. Тем не менее, я не могу найти ссылку на это кэширование и не знаю, как его очистить или отключить.
Я хотел бы получить инструкции по работе с кешем, предложения о том, что еще может вызывать эти симптомы, или другие предлагаемые диагностические действия, которые могут быть полезны.
4 ответа
Я наконец откопал непонятную команду из MSDN, которая исправляет это:
ServicePointManager.DnsRefreshTimeout = 0;
Развернув все странные вещи, которые я пробовал ранее, я обнаружил еще одну нужную обстановку, наряду с приведенной выше; для объекта запроса отключите keep-alive:
request.KeepAlive = false;
Поздний ответ, конечно, но я нашел, что это решение работало лучше, чем принятый ответ. В моем сценарии я тестирую соединения SQL и не могу применить существующий ответ, так как у меня нет request.KeepAlive
установить.
На этой странице Брайана Манчини ("сумасшедшая индейка") подробно рассказывается о его приключении по очистке кеша 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);
}
}
Если вы хотите оставить DnsRefreshTimeout > 0, вы можете обновить кеш, сделав вызов:
System.Net.Dns.GetHostEntry("example.com");
Вы можете использовать System.Diagnostics.Process для запуска ipconfig /flushdns