C# HttpWebRequest - Timeout obwohl Internetverbindung vorhanden

Fou-Lu

Lt. Junior Grade
Registriert
Aug. 2006
Beiträge
290
Hallo Leute,
ich machs kurz und knapp.

Hab nen Service der in einem bestimmten Intervall eine PHP Datei bei mir auf dem Webspace abruft (liefert nur aktuelle externe IP zurück). Dies protokolliert er im Eventlog.

Funktioniert auch wunderbar, wenn die Verbindung getrennt wird dann protokolliert er einen Timeout, das ist auch gut so.

Jetzt aber das Problem: Wenn die Verbindung getrennt wird und dann wieder hergestellt, dann meldet er mir trotzdem Timeout obwohl die Verbindung schon lange wieder da ist.

Hat jemand eine Idee woran das liegt und/oder wie man das beheben kann?


PHP:
string message = "Anfrage gestartet um: " + DateTime.Now.ToString() + "\r\n\r\n";

try {
	// externe IP-Adresse herausfinden
	httpRequest = (HttpWebRequest)HttpWebRequest.Create(uri);
	httpRequest.Method = "GET";
	httpRequest.Timeout = 10000;
	httpRequest.ContentType = "application/x-www-form-urlencoded";

	response = (HttpWebResponse)httpRequest.GetResponse();

	byte[] byteData = new byte[response.ContentLength];

	Stream stream = response.GetResponseStream();
	stream.Read(byteData, 0, byteData.Length);
	stream.Close();

	message += "Externe Server IP-Adresse: " + ASCIIEncoding.ASCII.GetString(byteData);
} catch (Exception ex) {
	message += ex.Message;
}

this.EventLog.WriteEntry(message);

Der obige Code wird in einem Timer_Elapsed Event ausgeführt.
 
Wie oft löst dein Timer denn aus? Das Timeout ist ja auf 10 Sekunden gestellt.
Es könnte ein Problem sein wenn der Timer ebenfalls alle 10 Sekunden oder kürzer auslöst.

Noch verzwickter wäre es wenn httpRequest und response keine Objekte werden die im Elapsed-Event definiert werden, sondern wenns "globale" Objekte wären.
 
Zuletzt bearbeitet:
Evtl. weil der Request dann übertragen wird, während keine Verbindung besteht, und dementsprechend keine Antwort kommt? Ist jetzt geraten, aber sowas kann ja an jeder Stelle der Kommunikation auftreten.
 
Versuche mal alle objekte korrekt zu disposen, am besten mit using statements dann wird es vermutlich klappen.
Hatte auch mal so ein ähnliches Problem und da lag es daran.
 
@DocWindows:
Der Timer wird derzeit alle 2 Minuten ausgelöst. Soll aber individuell eingestellt werden können (ab einer Minute und aufwärts :) )
Die Request und Response Instanzierungen sind nicht global, sondern lokal (wie aus dem Quelltext-Ausschnitt auch zu entnehmen).

@KamehamehaX10:
Es ist so, dass der Request ganz normal funktioniert solang eine Verbindung da ist. Dann bricht diese ab und es kommt zu einem Timeout.
Doch wenn die Verbindung "wiederhergestellt" ist, dann kommts nach wie vor zu einem Timeout... verstehe aber nicht wieso....

Die Objekte werden schließlich bei jedem Elapsed-Event neu instanziert und Verbindung ist ja auch da...

@UnKnOwN_86:
Ja das mit dem Disposen dachte ich auch, aber da gibts das Problem, dass diese Klassen zum einen nicht Disposable sind und zum anderen ja bei jedem Aufruf eine neue Instanz erstellt wird, deswegen sollte es so oder so keine Rolle spielen.... :(


Kann es vielleicht daran liegen, dass es als Windows-Service läuft? Müssen da vielleicht besondere Umstände beachtet werden?
Werds jetzt nochmal als Windows-Forms-Application testen, ob dieser Fehler dann auch wieder auftritt ;)
Ergänzung ()

Also jetzt versteh ich die Welt nicht mehr....

Habe nun den Timeout von 10 Sekunden gelöscht und den Standard-Timeout beibehalten.
Wenn ich jetzt das Kabel ziehe und wieder anstecke, dann protokolliert er mir alles richtig.

Wenn ich aber den Adapter deaktiviere und wieder aktiviere, dann spinnt die Anwendung rum.
Bei www.heise.de kommt dann immer ein Timeout und bei dem Request an mein eigenen Webspace klappt alles wunderbar.

Hier der aktuelle Code:
PHP:
textBox1.AppendText("Anfrage gestartet um: " + DateTime.Now.ToString() + "\r\n");

try {
	// versucht www.heise.de zu erreichen um die Verbindung zu prüfen
	HttpWebRequest httpRequest = (HttpWebRequest)HttpWebRequest.Create(heise_url);
	httpRequest.Method = "GET";
	httpRequest.ContentType = "application/x-www-form-urlencoded";
	HttpWebResponse response = (HttpWebResponse)httpRequest.GetResponse();

	textBox1.AppendText("www.heise.de gab eine Antwort zurück!\r\n");

	httpRequest = null;
	response = null;
} catch(Exception ex) {
	textBox1.AppendText(ex.Message + "\r\n");
}

try {
	// externe IP-Adresse herausfinden
	HttpWebRequest httpRequest = (HttpWebRequest)HttpWebRequest.Create(con_url);
	httpRequest.Method = "GET";
	httpRequest.ContentType = "application/x-www-form-urlencoded";

	HttpWebResponse response = (HttpWebResponse)httpRequest.GetResponse();

	byte[] byteData = new byte[response.ContentLength];

	Stream stream = response.GetResponseStream();
	stream.Read(byteData, 0, byteData.Length);
	stream.Close();

	textBox1.AppendText("Externe Server IP-Adresse: " + ASCIIEncoding.ASCII.GetString(byteData));

	httpRequest = null;
	response = null;
} catch (Exception ex) {
	textBox1.AppendText("\r\nException: " + ex.Message);
}

textBox1.AppendText("\r\n\r\n--------------------------------------------------\r\n\r\n");
Ergänzung ()

Ok Leute hat sich erledigt. Problem gelöst.

Habe jetzt statt HttpWebRequest einfach die WebClient-Klasse verwendet.
Damit funktioniert alles wunderbar ;)
 
So funktionierts mit HttpWebRequest, ich habe keine Probleme bemerkt wenn man HttpWebResponse korrekt disposed.

Code:
using System;
using System.IO;
using System.Net;
using System.Threading;

namespace ConsoleApplication1
{
    class Program
    {
        private static string con_url = "https://www.computerbase.de";
        private static string heise_url = "http://www.heise.de";

        static void Main(string[] args)
        {
            while(true)
            {
                Console.WriteLine("Anfrage gestartet um: " + DateTime.Now.ToString() + "\r\n");

                try
                {
                    // externe IP-Adresse herausfinden
                    HttpWebRequest httpRequest = HttpWebRequest.CreateHttp(con_url);
                    httpRequest.Timeout = 10000;
                    httpRequest.Method = "GET";
                    httpRequest.ContentType = "application/x-www-form-urlencoded";

                    using (var response = (HttpWebResponse)httpRequest.GetResponse())
                    {

                    }

                    Console.WriteLine(con_url + " gab eine Antwort zurück!\r\n");
                }
                catch (Exception ex)
                {
                    Console.WriteLine("\r\nException: " + ex.Message);
                }

                try
                {
                    // versucht www.heise.de zu erreichen um die Verbindung zu prüfen
                    HttpWebRequest httpRequest = HttpWebRequest.CreateHttp(heise_url);
                    httpRequest.Timeout = 10000;
                    httpRequest.Method = "GET";
                    httpRequest.ContentType = "application/x-www-form-urlencoded";

                    using (var response = (HttpWebResponse)httpRequest.GetResponse())
                    {

                    }

                    Console.WriteLine(heise_url + " gab eine Antwort zurück!\r\n");
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.Message + "\r\n");
                }

                Console.WriteLine("\r\n\r\n--------------------------------------------------\r\n\r\n");
                Thread.Sleep(2000);
            }
        }
    }
}
 
Zurück
Oben