2012-01-25 17 views
14

Ho un programma .NET in esecuzione su Ubuntu attraverso Mono 2.10HttpWebRequest NameResolutionFailure eccezione .NET (con Mono su Ubuntu)

Il programma scarica una pagina web tramite un HttpWebRequest ogni minuto o giù di lì che funziona bene la maggior parte del tempo :

 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(); 
      } 
     } 

Il problema è che dopo pochi giorni ho iniziare a ricevere le eccezioni sollevate:

 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 

Il server è ancora Abel per risolvere DNS, per esempio

wget http://www.google.com 

restituirà il file senza alcun problema soltanto come volontà ping e altri comandi che risolvono DNS.

Tuttavia, il mio programma continuerà a generare quell'eccezione fino a quando non lo riavvio. Dopo aver riavviato l'applicazione, riprenderà a funzionare come dovrebbe.

Ho controllato i conteggi di file aperti sul sistema (400 ish), l'utilizzo della memoria (327mb di 4gb), l'utilizzo della CPU (2-3%) e tutti sono OK.

Qualche idea?

risposta

9

È possibile risolverlo traducendo il nome host in ip e aggiungere il nome host alla collezione Headers o alla proprietà Host.

Se l'URL è http://example.com/uri. Risolvi l'host da solo. Supponiamo che sia 1.2.3.4. Sarà http://1.2.3.4/uri. Ora aggiungi l'intestazione Host: example.com alla tua richiesta. Penso che si possa fare impostando la proprietà HttpWebRequest.Host.

+1

Significa cercare l'IP prima di usare "Dns.GetHostEntry (domainName);" o qualcosa del genere? Supponevo che avrebbe causato lo stesso problema se si trattava di un problema DNS, o sospetti che si tratti di un bug in Mono/.NET? – antfx

+0

Sì, tramite codice programmato o hard. Questo assicura che 'HttpWebRequest' non risolva DNS ogni volta che si effettua una richiesta. –

+0

hmm, OK, non è la soluzione ideale in quanto lascia ancora il problema lì, ma suppongo che potrei fare una chiamata a 'GetHostEntry' sempre un'ora o così per verificare gli aggiornamenti in DNS ed evitare il codice. Mi piacerebbe davvero trovare il problema anche se questo ha effetto solo su alcuni dei miei server, non tutti (ho 50) – antfx

0

Ho riscontrato lo stesso problema nella mia applicazione mono su raspbian. Ho provato diverse soluzioni descritte in questo e in altri thread, ma nessuno ha funzionato. Alla fine, sono stato in grado di risolvere il problema modificando il name server in /etc/resolv.conf a quelli di Google https://developers.google.com/speed/public-dns/

Mirko

2

So che questo è un vecchio post, ma stavo affrontando lo stesso errore, quindi pensato per condividere la soluzione.

  1. La soluzione migliore che ho trovato, quando si verifica questa eccezione, mentre il Wifi è collegato, è solo quello di ripetere la mia chiamata server con un leggero sonno in mezzo. Funziona la maggior parte del tempo, altrimenti se la seconda chiamata fallisce, annullo la richiesta.
  2. Questo errore può anche aumentare se il Wi-Fi dell'utente è molto instabile o il segnale è molto basso. Lo stesso errore si verifica se non è disponibile alcuna connessione Internet , anche se connessa a Wifi.

Ciò è in linea con le mie ans on:

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

+0

Cambiando il wifi dalla mia pessima internet di lavoro per legare il mio LTE, questo errore è scomparso. – locrizak

3

Beh io uso il HttpClient - ma potrebbe essere un problema simile. Ho avuto lo stesso problema su un dispositivo Android (ha funzionato su un Windows Phone) ...Ma dopo aver aggiunto l'host all'intestazione, ha funzionato!

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

È comunque possibile utilizzare il nome nella URL (non c'è bisogno di utilizzare l'indirizzo IP)

+0

hai un campione riproducibile? –

+1

No. Quando l'host è stato impostato una volta, il setter può essere rimosso ... Penso che il dispositivo contenga il proprio "record DNS" per riferimenti futuri. Non ha funzionato prima ho aggiunto la linea, ma ha funzionato dopo. Quando ho provato a rimuovere nuovamente la linea, ha funzionato ... Al momento non ho un altro dispositivo per poterlo riprodurre. Nota: ho utilizzato un nuovo dominio creato che il dispositivo non ha mai visitato prima ed è un tipo di soluzione completamente diverso (Xamarin.Android). –

0

stavo ottenendo questo errore quando ho iniziato l'applicazione mobile (Android o iOS non importa) senza connessione internet. Dopo aver ripristinato la connessione, ogni richiesta restituisce "NameResolutionFailure exception". Ho dovuto aspettare 120 secondi per avere di nuovo la richiesta HTTP a funzionare. Impostando la seguente riga di codice in qualsiasi punto dell'avvio dell'app, l'errore era finalmente risolto.

System.Net.ServicePointManager.DnsRefreshTimeout = 0; 

Il valore predefinito di DnsRefreshTimeout è 120 secondi.

+0

Provato e non funziona con WebClient – Pierre

+0

Non sono sicuro, stavo usando solo HttpClient. – gts

+0

Hai impostato 'request.KeepAlive = false;'? – Pierre