Laden...

merkwürdiges verhalten beim lesen von NetworkStream

Erstellt von SamySays vor 6 Jahren Letzter Beitrag vor 6 Jahren 2.621 Views
S
SamySays Themenstarter:in
22 Beiträge seit 2014
vor 6 Jahren
merkwürdiges verhalten beim lesen von NetworkStream

Hi@all.
Wie schon im Titel angedeutet verhält sich NetworkStream beim lesen merkwürdig.
Ich hab dazu hier mal etwas Code:

static void Main(string[] args)
{

	TcpClient client = new TcpClient("de.html.net", 80);

	byte[] request = Encoding.UTF8.GetBytes(
		"GET / HTTP/1.1\n"
		+ "Host: de.html.net\n"
		+ "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:58.0) Gecko/20100101 Firefox/58.0\n"
		+ "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\n"
		+ "Accept-Language: de,en-US;q=0.7,en;q=0.3\n"
		+ "Connection: keep-alive\n\n"
		);

	client.GetStream().Write(request, 0, request.Length);

	using (MemoryStream memory = new MemoryStream())
	using (NetworkStream network = client.GetStream())
	{
		byte[] response = new byte[1024];
		int countReadedBytes;

		while ((countReadedBytes = network.Read(response, 0, response.Length)) > 0)
		{
			memory.Write(response, 0, countReadedBytes);
			// 1. Console.WriteLine(Encoding.UTF8.GetString(response));
		}

		// 2. Console.WriteLine(Encoding.UTF8.GetString(memory.ToArray()));
	}

	Console.WriteLine("\n\n--- END ---");
	Console.ReadKey();

}

Jetzt zum merkwürdigen Verhalten.
Wenn ich das Programm mit diesem Code ausführe, wirkt es so, als ob es irgendwo beim lesen des NetworkStreams festhängt aber wenn man eine Weile wartet, dann gibt es irgendwann doch noch "--- END --" aus.

Wenn man jetzt die Kommentarzeile "// 1. Console..." dekommentiert dann stellt man fest, dass das Programm ein paar Daten ausgibt, ab einem bestimmten Punkt eine Weile stehen bleibt und dann direkt "--- END ---" ausgibt, ohne die noch fehlenden Daten auszugeben.

Wenn man allerdings anstatt der Kommentarzeile "// 1. Console..." die Kommentarzeile "// 2. Console..." dekommentiert, bleibt das Programm zwar auch an einer bestimmten stelle kurzzeitig stehen, gibt mir aber dann den kompletten Quellcode der Internetseite aus, bevor es dann "--- END ---" ausgibt.

Nach dieser Beschreibung nun zu meinen Fragen:

  1. Warum gibt die 1. "Console.Write"-Anweisung nur einen Teil des Quellcodes der gelesenen Internetseite zurück und die 2. den gesamten Quellcode, obwohl doch eigentlich beide das gleiche ausgeben müssten?

  2. Wie kommt diese recht lange Wartezeit ab einem bestimmten Punkt des lesens vom NetworkStream zustande?

  3. Wie kann ich diese Wartezeit vermeiden?

T
2.219 Beiträge seit 2008
vor 6 Jahren

Spar dir das selbst gebastelte und mach einen WebRequest.
Für solche Basic Sachen, wie Http Anfragen kannst du ganz einfach mit WebRequest dir die Daten holen.

Du betreibst hier zu viel Aufwand um einen einfachen Request zu machen obwohl C#/.NET hier schon sehr einfache Klassen hat.

Link:
WebRequest.Create-Methode: (String)

Nachtrag:
Hier der Beispiel Code:


			WebRequest request = WebRequest.Create("http://de.html.net");

			using (WebResponse response = request.GetResponse())
			{
				using (StreamReader reader = new StreamReader(response.GetResponseStream()))
				{
					while(!reader.EndOfStream)
						Console.WriteLine(reader.ReadLine());
				}
			}

			Console.WriteLine("--- END ---");
			Console.ReadKey();

T-Virus

Developer, Developer, Developer, Developer....

99 little bugs in the code, 99 little bugs. Take one down, patch it around, 117 little bugs in the code.

S
SamySays Themenstarter:in
22 Beiträge seit 2014
vor 6 Jahren

Für solche Basic Sachen, wie Http Anfragen kannst du ganz einfach mit WebRequest dir die Daten holen.

Gibt es da auch eine Möglichkeit, Response-Headers und Inhalt der Seite abzufragen, wenn die Seite den Statuscode 503 zurückgibt? Wenn ich nämlich versuche so eine Seite mit WebRequest / WebResponse oder WebClient aufzurufen, wird mir ne System.Net.WebException geschmissen.

T
2.219 Beiträge seit 2008
vor 6 Jahren

Die WebException enthält hier auch einen Response.
Dort kannst du dann, wenn dieser gefüllt ist, dir auch alle Informationen rauslesen.
Dort hast du dann auch die Headers Eingeschaft, in der alle Infos drin stehen sollten.

Link:
WebException.Response-Eigenschaft

T-Virus

Developer, Developer, Developer, Developer....

99 little bugs in the code, 99 little bugs. Take one down, patch it around, 117 little bugs in the code.

30 Beiträge seit 2007
vor 6 Jahren

Hallo,

  1. Warum gibt die 1. "Console.Write"-Anweisung nur einen Teil des Quellcodes der gelesenen Internetseite zurück und die 2. den gesamten Quellcode, obwohl doch eigentlich beide das gleiche ausgeben müssten?

du gibst leider nicht das gleiche aus. In den Memory-Stream schreibst du den Inhalt des Arrays responce, aber nur jeweils soviele Bytes, wie du auch gelesen hast.

memory.Write(response, 0, countReadedBytes);

Das ist richtig 😃

Auf die Console gibst du jedoch immer den Inhalt des kompletten Arrays aus:

Console.WriteLine(Encoding.UTF8.GetString(response));

Und genau hier liegt das Problem. network.Read gibt eben nicht immer genau 1024 Bytes zurück.

Viele Grüße

Jens

S
SamySays Themenstarter:in
22 Beiträge seit 2014
vor 6 Jahren

@jbrand
Achso... OK, das hatte ich übersehen. Danke für deine Antwort.

@T-Virus
Auch dir danke für deine Antwort. Das wusste ich noch nicht.

Gibt es denn bei WebRequest / WebResponse oder WebClient eine Möglichkeit die Daten über einen SOCKS5-Proxy zu übertragen? Wenn das gehen würde, dann könnte ich damit wunderbar arbeiten.

T
2.219 Beiträge seit 2008
vor 6 Jahren

Hab zwar bisher keine Proxies verwendet, aber schau dir mal die Proxy Eigenschaft vom WebRequest an.
Vielleicht hilft die dir.

Link:
https://msdn.microsoft.com/de-de/library/system.net.webrequest.proxy(v=vs.110).aspx

T-Virus

Developer, Developer, Developer, Developer....

99 little bugs in the code, 99 little bugs. Take one down, patch it around, 117 little bugs in the code.

S
SamySays Themenstarter:in
22 Beiträge seit 2014
vor 6 Jahren

Hab zwar bisher keine Proxies verwendet, aber schau dir mal die Proxy Eigenschaft vom WebRequest an.
Vielleicht hilft die dir.

Link:

>

Leider nicht. Die Proxy-Eigenschaft von WebRequest funktioniert nicht mit SOCKS-Proxies.

T
2.219 Beiträge seit 2008
vor 6 Jahren

Hab mal etwas gegoogelt.
Scheinbar kann der WebRequest selbst nicht direkt mit Socks5 umgehen.
Leider fehlt mir die direkte Erfahrung um dir weiterhelfen zu können.
Googel spuckte mir aber bei StackOverflow folgendes aus.

Link:
https://stackoverflow.com/questions/13122369/use-webclient-with-socks-proxy

Dort wird zum einen gezeigt, wie man von WebClient ableitet und dies dann implementieren kann.
Aber auch BetterHttpClient wurde dort verlinkt, was wohl damit umgehen kann.

Je nachdem was dir mehr liegt, kannst du dir die Lösungen mal anschauen.
Würde eher zu BetterHttpClient raten, anstelle es selbst zu basteln.

Link:
https://github.com/Yozer/BetterHttpClient

T-Virus

Developer, Developer, Developer, Developer....

99 little bugs in the code, 99 little bugs. Take one down, patch it around, 117 little bugs in the code.

W
872 Beiträge seit 2005
vor 6 Jahren

Ich benutze für Socks5 Privoxy als Proxy.