【问题标题】:System.Net.WebRequest not respecting hosts fileSystem.Net.WebRequest 不尊重主机文件
【发布时间】:2020-08-05 02:32:56
【问题描述】:

有没有办法让System.Net.WebRequestSystem.Net.WebClient 尊重hostslmhosts 文件?

例如:在我的主机文件中,我有:

10.0.0.1  www.bing.com

当我尝试在浏览器(IE 和 FF)中加载 Bing 时,它无法按预期加载。

Dns.GetHostAddresses("www.bing.com")[0]; // 10.0.0.1 
WebRequest.Create("http://10.0.0.1").GetResponse(); // throws exception (expected)
WebRequest.Create("http://www.bing.com/").GetResponse(); // unexpectedly succeeds

同样:

WebClient wc = new WebClient();
wc.DownloadString("http://www.bing.com"); //succeeds 

为什么System.Net.Dns 尊重主机文件而System.Net.WebRequest 忽略它?我需要更改哪些内容才能使 WebRequest 尊重主机文件?

附加信息:

  • 如果我禁用 IPv6 并将我的 IPv4 DNS 服务器设置为 127.0.0.1,上述代码将按预期工作(失败)。但是,如果我将正常的 DNS 服务器作为备用服务器添加回来,意外的行为会再次出现。
  • 我已经在 3 个 Win7 和 2 个 Vista 盒子上复制了这个。唯一不变的是我公司的网络。
  • 我正在使用 .NET 3.5 SP1 和 VS2008

编辑

根据@Richard Beier 的建议,我尝试了System.Net 追踪。跟踪 ON 时,WebRequest 会失败。但是,一旦我将跟踪 OFF 关闭,行为就会恢复到意外的成功。我已经在调试和发布模式下在与以前相同的机器上重现了这个。

编辑 2

这原来是公司代理给我们带来的问题。我们的解决方案是为我们的测试机器定制一个代理配置脚本,让“bing.com”指向 DIRECT 而不是默认代理。

【问题讨论】:

  • 我猜您正在通过网络中的代理工作。你的浏览器是做什么的?
  • IE 和 FF 都按预期运行(尝试从 hosts 文件中指示的服务器加载)。
  • 你试过ipconfig /flushdns吗?
  • 是的,ipconfig /displaydns 显示 hosts 文件中的条目。

标签: c# .net hosts


【解决方案1】:

我认为@Hans Passant 在这里发现了问题。看来您在 IE 中设置了代理。

Dns.GetHostAddresses("www.bing.com")[0]; // 10.0.0.1  

这是有效的,因为您要求操作系统获取www.bing.com 的 IP 地址

WebRequest.Create("http://www.bing.com/").GetResponse(); // unexpectedly succeeds

这是有效的,因为您要求框架从服务器名称中获取路径。该框架使用 IE 前端使用的相同引擎和设置,因此如果您的公司已通过 GPO 指定您使用公司代理服务器,则解析www.bing.com 的 IP 地址的代理服务器而不是您。

WebRequest.Create("http://10.0.0.1").GetResponse(); // throws exception (expected) 

此方法有效/失败,因为您已要求框架从特定服务器(通过 IP)获取网页。即使您设置了代理,该代理仍然无法连接到该 IP 地址。

我希望这会有所帮助。

乔纳森

【讨论】:

  • 你说得对,我支持公司代理,但我不确定我是否遵循你的逻辑。我希望WebRequest.Create() 会表现出与 IE 相同的行为,但事实并非如此。 IE 中的 Bing.com 尝试加载 10.0.0.1 时超时
  • 检查 web.config 以确保没有设置 defaultProxy - 删除这个为我修复了上述问题。
【解决方案2】:

我在 Windows 7 上使用 VS 2010,但无法重现。我进行了相同的主机文件更改并运行了以下代码:

Console.WriteLine(Dns.GetHostAddresses("www.bing.com")[0]);             // 10.0.0.1     
var response = WebRequest.Create("http://www.bing.com/").GetResponse(); // * * *
Console.WriteLine(new StreamReader(response.GetResponseStream()).ReadToEnd());

我在标记为“* * *”的行上遇到了异常。以下是异常详情:

System.Net.WebException was unhandled
  Message=Unable to connect to the remote server
  Source=System
  StackTrace:
       at System.Net.HttpWebRequest.GetResponse()
       at ConsoleApplication2.Program.Main(String[] args) in c:\Data\Projects\ConsoleApplication2\ConsoleApplication2\Program.cs:line 17
  InnerException: System.Net.Sockets.SocketException
       Message=A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond 10.0.0.1:80
       Source=System
       ErrorCode=10060

也许这是早期 .NET 版本的问题,现在已在 .NET 4 / VS 2010 中修复?您使用的是哪个版本的 .NET?

我还从 2007 年发现了这个 thread,其他人也遇到了同样的问题。那里有一些很好的建议,包括:

  • 开启system.net tracing

  • 通过使用 Dns.GetHostAddresses() 将其解析为 IP 来解决此问题。然后将 IP 放入 URL - 例如“http://10.0.0.1/”。不过,这可能不是您的选择。

在上面的帖子中,mariyaatanasova_msft 还说:“HttpWebRequest 使用 Dns.GetHostEntry 来解析主机,因此您可能会得到与 Dns.GetHostAddresses 不同的结果”。

【讨论】:

  • 我使用的是 VS2008 和 3.5 SP1。 GetHostEntry 给了我与GetHostAddress 相同的输出。我会调查追踪。谢谢。
  • 根据您的建议启用 System.Net 跟踪。启用跟踪后,WebRequest 会按预期失败。随着追踪,它又回到了意外的成功。想法?
  • 这很奇怪——我没有一个好的答案。 Hans Passant 和 Jonathan Stanton 在代理方面有很好的观点。但是如果 IE 使用代理并且仍然尊重您的主机文件,那么主机文件也应该在使用 WebRequest 时覆盖代理。正如 mwalker 所建议的那样,我唯一能建议的就是尝试禁用代理。您还可以尝试使用 Wireshark 或网络监视器等数据包嗅探器来查看线路上发生的情况 - 但我不确定这是否会有所帮助。如果您看到对 www.bing.com 的 DNS 请求,则表明它没有使用 hosts 文件,但没有解释原因。
【解决方案3】:

您应该覆盖默认代理。 HttpWebRequest 和 WebRequest 将设置默认代理(如果 Internet Explorer 中存在)并且您的文件 hosts 将被绕过

request.Proxy = new WebProxy();

以下只是代码示例:

try
{
   HttpWebRequest request = (HttpWebRequest)WebRequest.Create("www.bing.com");
   request.Proxy = new WebProxy();
   request.Method = "POST";            
   request.AllowAutoRedirect = false;

   HttpWebResponse response = (HttpWebResponse)request.GetResponse();               
   if (response.StatusCode == HttpStatusCode.OK)
   {
      //some code here
   }
}
catch (exception e)
{
   //Some other code here
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多