在.NET(在Ubuntu上使用Mono)中,HttpWebRequest出现了名称解析失败的异常。

15

我有一个运行在Ubuntu上的.NET程序,通过Mono 2.10实现。

该程序每隔一分钟左右通过HttpWebRequest下载一个网页,大多数情况下都能正常工作:

        String result;
        WebResponse objResponse;
        WebRequest objRequest = System.Net.HttpWebRequest.Create(url);

        using (objResponse = objRequest.GetResponse())
        {
            using (StreamReader sr =
               new StreamReader(objResponse.GetResponseStream()))
            {
                result = sr.ReadToEnd();
                // Close and clean up the StreamReader
                sr.Close();
            }
        }
问题是几天后我开始收到异常抛出:
        DateTime: 01/25/2012 08:15:41
        Type: System.Net.WebException
        Error: Error: NameResolutionFailure
        Stack:
          at System.Net.HttpWebRequest.EndGetResponse (IAsyncResult asyncResult) [0x00000] in <filename unknown>:0
          at System.Net.HttpWebRequest.GetResponse () [0x00000] in <filename unknown>:0
          at socks_server.Program.readHtmlPage (System.String url) [0x00000] in <filename  unknown>:0
          at socks_server.Program.getAccessKeysProc () [0x00000] in <filename unknown>:0
服务器仍然能够解析DNS,例如
 wget http://www.google.com

调用该方法不会出现任何问题,同样适用于解析DNS的ping和其他命令。

然而,我的程序在抛出该异常后将继续发生,直到我重新启动它。在重新启动应用程序后,它将再次按照预期开始工作。

我已经检查了系统上的打开文件计数(大约为400个),内存使用情况(4GB中的327MB),CPU使用率(2-3%)等,所有都正常。

有什么想法吗?

5个回答

9
您可以通过将主机名翻译为IP并将主机名添加到Headers集合或Host属性中来解决此问题。
如果您的url是http://example.com/uri。请自行解析主机。假设它是1.2.3.4。它将成为http://1.2.3.4/uri。现在将Host: example.com标头添加到您的请求中。我认为可以通过设置HttpWebRequest.Host属性来完成。

1
你的意思是事先使用 Dns.GetHostEntry(domainName); 或类似方法查找IP地址吗?我认为如果真的是DNS问题,这样做会导致相同的问题,或者你怀疑这是Mono/.NET中的一个错误? - antfx
是的,可以通过编程或硬编码来实现。这可以确保每次发出请求时 HttpWebRequest 不会解析 DNS。 - Shiplu Mokaddim
嗯,好吧,这并不是理想的解决方案,因为它仍然存在问题,但我想我可以每小时调用 GetHostEntry 一次,以检查 DNS 中的更新并避免硬编码。不过,我真的很想找到问题所在,因为这只影响我的一些服务器,而不是所有服务器(我有50个)。 - antfx
有人找到了解决方案吗?我也遇到了同样的问题,这个主机和IP的解决方法对我不起作用。 - Sagar Panwala

3

我使用HttpClient - 但可能存在类似的问题。我在Android设备上遇到了同样的问题(它可以在Windows Phone上运行)...但是当我将Host添加到标题中后,它就可以工作了!

client.DefaultRequestHeaders.Host = "mydomain.com";

您仍然可以在URL中使用名称(无需使用IP地址)。


你有可重现的样本吗? - Alex Sorokoletov
1
不。一旦主机设置过,就可以移除setter...我认为该设备包含了自己的“DNS记录”以供未来参考。在添加这行代码之前它无法工作,但是加上之后就可以工作了。当我尝试再次删除该行时,它仍然工作。目前我没有另一台设备可以重现此问题。注意:我使用了一个设备之前从未访问过的新创建的域 - 这是完全不同类型的解决方案(Xamarin.Android)。 - Kim Rasmussen

3

我知道这是一篇旧文章,但我也遇到了同样的错误,所以想分享解决方案。

  1. 当Wifi连接时出现该异常时,我发现最好的解决方案就是稍微等待一下,然后重试我的服务器调用。这在大多数情况下都有效,否则如果第二个调用失败,我会取消请求。
  2. 如果用户的Wifi非常不稳定或信号非常低,则也可能引发此错误。如果完全没有互联网连接,即使连接到Wifi,也会出现相同的错误。

这与我的答案一致:

System.Net.WebException: Error: NameResolutionFailure when Calling WCF Services throwing exception in mono android application


将WiFi从我的劣质工作网络更改为LTE共享网络使这个错误消失了。 - locrizak
不是和你的问题一样,但是提到 WiFi 让我意识到我的问题所在。我的应用程序连接到我们网络内部的一个 API,当我断开 WiFi 后,它就无法找到该 API 了。 - Lewis Hamill
我还尝试了带有轻微延时的重试,但问题没有消除。 - Eric Legault

0

我在我的Raspbian上的mono应用程序中遇到了相同的问题。我尝试了本主题和其他主题中描述的不同解决方案,但都没有起作用。最终,我通过将/etc/resolv.conf中的名称服务器更改为谷歌服务器https://developers.google.com/speed/public-dns/来解决了问题。

Mirko


0
当我在没有网络连接的情况下启动移动应用程序(无论是Android还是iOS)时,我遇到了这个错误。恢复连接后,每个请求都返回“NameResolutionFailure异常”。我不得不等待120秒才能再次使http请求正常工作。在应用程序启动的任何位置设置以下代码行,最终解决了该错误。
System.Net.ServicePointManager.DnsRefreshTimeout = 0;

默认的DnsRefreshTimeout值为120秒。


不确定,我只使用了 HttpClient。 - neurona.dev
你设置了 request.KeepAlive = false; 吗? - Pierre

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