Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 | Suche | FAQ

Hauptmenü
myCSharp.de
» Startseite
» Forum
» Suche
» Regeln
» Wie poste ich richtig?

Mitglieder
» Liste / Suche
» Wer ist online?

Ressourcen
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Microsoft Docs

Team
» Kontakt
» Cookies
» Spenden
» Datenschutz
» Impressum

  • »
  • Community
  • |
  • Diskussionsforum
Streamreader --> Wann "leer"???
SGT_BOB
myCSharp.de - Member



Dabei seit:
Beiträge: 125
Herkunft: Aachen

Themenstarter:

Streamreader --> Wann "leer"???

beantworten | zitieren | melden

Hallo Leute.

Schreibe gerade ein Programm mit Serverzugriff (FTP-Client). Vieles funktioniert auch reibungslos, allerdings hänge ich schon länger an folgendem Problem.

Ich möchte die Antworten vom Server in einem string speichern, den ich später für die Statusausgabe für meine WinForm bzw. zur weiteren Verarbeitung brauche.

Das Problem fängt aber an sobald der Server mehrere aufeinander folgende Antworten sendet.


private void GetResponse(StreamReader stream)
		{
			try
			{
				serverResponse = "";
				string temp = "";
				
				int count = 0;
				Console.WriteLine("+++ GetResponse(StreamReader stream) +++");
				do
				{
					Console.WriteLine("Durchlauf " + (count += 1));

					temp = stream.ReadLine() + CRLF;
					Console.WriteLine("temp: " + temp + " --> temp.Length = " + temp.Length);
					
						serverResponse += temp;


				}while(temp.Length ≥ 3 && temp.Length != 0);
				

			}
			catch(Exception ex)
			{
				Console.WriteLine(ex.ToString());
			}
			Console.WriteLine("GetResponse-ENDE");
		}

Manchmal funktioniert es, manchmal nicht. Irgendwie hab ich das Gefühl das hier beim 3. Durchlauf erfolglos versucht wird der Stream einzulesen. Das kommt dabei raus.


+++ GetResponse(StreamReader stream) +++
Durchlauf 1
temp: 226 Transfer complete
--> temp.Length = 23
Durchlauf 2
temp: 250 CWD command successful
--> temp.Length = 28
Durchlauf 3


Wie kann ich überprüfen ob der Stream "leer" ist??? Steh irgendwie auf dem Schlauch...

Danke schonmal.

Mfg SGT_BOB
*************************
Ich bin root, ich darf das...
root>_
*************************
private Nachricht | Beiträge des Benutzers
herbivore
myCSharp.de - Experte

Avatar #avatar-2627.gif


Dabei seit:
Beiträge: 52329
Herkunft: Berlin

beantworten | zitieren | melden

Hallo SGT_BOB,

der bisherige Ansatz ist m.E. komplett ungeeignet, weil die "Länge" des Streams davon abhängt, wieviele Bytes schon beim Client eingetroffen sind und nicht wieviele noch kommen werden. Macht der Server eine Zwischenpause, könntest du denken, dass der Stream schon zu Ende ist.

Ich denke, du musst wissen, wieviele Bytes von Server kommen sollen/werden und muss dann genau soviele einlesen.

herbivore
private Nachricht | Beiträge des Benutzers
SGT_BOB
myCSharp.de - Member



Dabei seit:
Beiträge: 125
Herkunft: Aachen

Themenstarter:

beantworten | zitieren | melden

Hallo.

Erstmal danke.

Also meinst du über ein Byte-Array sollte es hier besser funktionieren.
Aber woher weiß ich denn vorher wieviele Bytes da kommen sollen, oder bestimme ich das selbst? Wie gesagt es handelt sich um einen FTP-Client und der soll auf "allen" Servern funktionieren.

Hab da echt ein Verständnisproblem. X(

Mfg

SGT_BOB
*************************
Ich bin root, ich darf das...
root>_
*************************
private Nachricht | Beiträge des Benutzers
herbivore
myCSharp.de - Experte

Avatar #avatar-2627.gif


Dabei seit:
Beiträge: 52329
Herkunft: Berlin

beantworten | zitieren | melden

Hallo SGT_BOB,

ich habt das FTP-Protokoll auch nicht genau im Kopf, aber ich denke, wenn du dir die RFC anguckst, steht da bestimmt, wie man das Ende der Datei erkennt.

herbivore
private Nachricht | Beiträge des Benutzers
SGT_BOB
myCSharp.de - Member



Dabei seit:
Beiträge: 125
Herkunft: Aachen

Themenstarter:

beantworten | zitieren | melden

Hallo.

Nochmal danke für deine Hilfe. Leider steh ich noch immer auf dem Schlauch.

@herbivore:

Soweit das ich Dateien herunter- bzw. herauflade bin ich noch gar nicht. Momentan geht es mir nur darum wie ich die Antworten vom Server bekomme. Sende ich z.B. über das Programm einen "List"-Befehl sieht das ganze so aus und funktioniert einwandfrei.


+++ Connected = True +++
ftp-> 150 Opening ASCII mode data connection for file list

drwxr-xr-x 4 ftp ftp 93 May 29 22:04 .
drwxr-xr-x 4 ftp ftp 93 May 29 22:04 ..
-rw-r--r-- 1 ftp ftp 156 Jan 1 15:21 Closed.htm
-rw-r--r-- 1 ftp ftp 136 Jan 1 15:21 Home.htm
drwxr-xr-x 2 ftp ftp 34 Jan 1 15:21 Images
-rw-r--r-- 1 ftp ftp 228 Jan 1 15:21 Navi.htm
-rw-r--r-- 1 ftp ftp 585 Jan 1 15:21 index.htm
drwxr-xr-x 2 ftp ftp 6 May 29 22:04 test


Mein Problem scheint wirklich die "Antwortpause" vom Server zu sein, so wie es von dir bereits erwähnt wurde.

Leider gab mir das RFC auch nicht die Auskünfte die ich brauche. Ist vielleicht auch eher serverabhängig.

Wäre echt super wenn mir jemand einen Denkanstoß geben könnte, da ich nicht das nächste Projekt wegen solche eines "kleinen" Problems ins Nirvana schicken möchte.

Mfg

SGT_BOB


PS:

Könnte es vielleicht über eine Art "Timeout-Kontrolle" gelöst werden??? Ich bekomme nämlich manchmal auch soetwas hier und dann springt er doch aus der Schleife raus.


226 Transfer complete
257 "/" is the current directory
421 Idle timeout (120 seconds): closing control connection
*************************
Ich bin root, ich darf das...
root>_
*************************
private Nachricht | Beiträge des Benutzers
herbivore
myCSharp.de - Experte

Avatar #avatar-2627.gif


Dabei seit:
Beiträge: 52329
Herkunft: Berlin

beantworten | zitieren | melden

Hallo SGT_BOB,
Zitat
Leider gab mir das RFC auch nicht die Auskünfte die ich brauche.
mir schon. :-) In RFC959 Abschnitt "4.2. FTP REPLIES" steht alles, was du wissen willst bzw. wissen musst.

Das ist vermutlich, was dich am meisten interessiert:
Zitat
Thus the format for multi-line replies is that the first line will begin with the exact required reply code, followed immediately by a Hyphen, "-" (also known as Minus), followed by text. The last line will begin with the same code, followed immediately by Space <SP>, optionally some text, and the Telnet end-of-line code.

The user-process then simply needs to search for the second occurrence of the same reply code, followed by <SP> (Space), at the beginning of a line, and ignore all intermediary lines. If an intermediary line begins with a 3-digit number, the Server must pad the front to avoid confusion.
herbivore
private Nachricht | Beiträge des Benutzers
SGT_BOB
myCSharp.de - Member



Dabei seit:
Beiträge: 125
Herkunft: Aachen

Themenstarter:

beantworten | zitieren | melden

Hallo.

Wahrscheinlich geh ich dir schon auf die Nerven
, aber irgendwie ist das scheinbar nicht das was ich brauche.
Wenn ich es richtig verstanden habe gilt das nur für eine Antwort die sich über mehrere Zeilen erstreckt. Aber das wird bei mir doch über ein "stream.ReadLine()" gelöst. Das heißt er liest doch eh zeilenweise aus dem Stream, aber ich habe manchmal das Gefühl, der Stream ist scheinbar leer und das Programm bleibt dann an dieser Stelle hängen, bis der FTP-Server mir eine Timeout-Meldung gibt, dann steht im Stream ja wieder etwas drin und er liest innerhalb der Schleife weiter.

Nochmal ein wenig Code und die entsprechende Ausgabe:


private void GetResponse(StreamReader stream)
		{
			try
			{
				serverResponse = "";
				string temp = "";
				
				int count = 0;
				
				Console.WriteLine("+++ GetResponse(StreamReader stream) +++");
				do
				{
					Console.WriteLine("Durchlauf " + (count += 1));

//					if(temp = stream.ReadLine() + CRLF)
					Console.WriteLine(stream.Peek());
					temp = stream.ReadLine() + CRLF;
					Console.WriteLine("temp: " + temp + " --> temp.Length = " + temp.Length);
					if(temp.Length ≥ 3 || !temp.Equals(CRLF))
					{					
						serverResponse += temp;
						Console.WriteLine("IF");
					}
					else
					{
						temp = "";
						Console.WriteLine("ELSE");
						break;
					}

				}while(temp.Length ≥ 3 && temp.Length != 0);
					


			}
			catch(Exception ex)
			{
				Console.WriteLine(ex.ToString());
			}
			Console.WriteLine("GetResponse-ENDE");
		}

einen "LIST"-Befehl und einen "PWD"-Befehl ausgeführt bringt mir exakt folgende Console-Ausgabe:


ftp-> 150 Opening ASCII mode data connection for file list
+++ GetResponse(StreamReader stream) +++
Durchlauf 1
100
temp: drwxr-xr-x 4 ftp ftp 93 May 29 22:04 .
--> temp.Length = 58
IF
Durchlauf 2
100
temp: drwxr-xr-x 4 ftp ftp 93 May 29 22:04 ..
--> temp.Length = 59
IF
Durchlauf 3
45
temp: -rw-r--r-- 1 ftp ftp 156 Jan 1 15:21 Closed.htm
--> temp.Length = 67
IF
Durchlauf 4
45
temp: -rw-r--r-- 1 ftp ftp 136 Jan 1 15:21 Home.htm
--> temp.Length = 65
IF
Durchlauf 5
100
temp: drwxr-xr-x 2 ftp ftp 34 Jan 1 15:21 Images
--> temp.Length = 63
IF
Durchlauf 6
45
temp: -rw-r--r-- 1 ftp ftp 228 Jan 1 15:21 Navi.htm
--> temp.Length = 65
IF
Durchlauf 7
45
temp: -rw-r--r-- 1 ftp ftp 585 Jan 1 15:21 index.htm
--> temp.Length = 66
IF
Durchlauf 8
100
temp: drwxr-xr-x 2 ftp ftp 6 May 29 22:04 test
--> temp.Length = 61
IF
Durchlauf 9
-1
temp:
--> temp.Length = 2
ELSE
GetResponse-ENDE
drwxr-xr-x 4 ftp ftp 93 May 29 22:04 .
drwxr-xr-x 4 ftp ftp 93 May 29 22:04 ..
-rw-r--r-- 1 ftp ftp 156 Jan 1 15:21 Closed.htm
-rw-r--r-- 1 ftp ftp 136 Jan 1 15:21 Home.htm
drwxr-xr-x 2 ftp ftp 34 Jan 1 15:21 Images
-rw-r--r-- 1 ftp ftp 228 Jan 1 15:21 Navi.htm
-rw-r--r-- 1 ftp ftp 585 Jan 1 15:21 index.htm
drwxr-xr-x 2 ftp ftp 6 May 29 22:04 test

+++ GetCurrentDir() +++
+++ GetResponse(StreamReader stream) +++
Durchlauf 1
-1
temp: 226 Transfer complete
--> temp.Length = 23
IF
Durchlauf 2
-1
temp: 257 "/" is the current directory
--> temp.Length = 34
IF
Durchlauf 3
-1 <-- Hier bleibt er kurz hängen
temp: 421 Idle timeout (120 seconds): closing control connection
--> temp.Length = 60
IF
Durchlauf 4
-1
temp:
--> temp.Length = 2
ELSE
GetResponse-ENDE
226 Transfer complete
257 "/" is the current directory
421 Idle timeout (120 seconds): closing control connection



Ich hoffe du kannst jetzt eher in meine Problematik einsteigen. Mir fehlt einfach die Möglichkeit das Auslesen des Streams abzubrechen wenn ich es möchte, nämlich dann wenn ich meine Daten (Status) habe. Die habe ich aber schon bevor die letzte Meldung (421 Idle timeout (120 seconds): closing control connection) kommt. Diese erscheint meines Erachtens nach ja nur, weil der Server die Verbindung wegen fehlender Aktivität abbricht.

Hoffe du (oder irgendwer) kann mir da weiterhelfen.

Mfg

SGT_BOB
*************************
Ich bin root, ich darf das...
root>_
*************************
private Nachricht | Beiträge des Benutzers
herbivore
myCSharp.de - Experte

Avatar #avatar-2627.gif


Dabei seit:
Beiträge: 52329
Herkunft: Berlin

beantworten | zitieren | melden

Hallo SGT_BOB,
Zitat
Wenn ich es richtig verstanden habe gilt das nur für eine Antwort die sich über mehrere Zeilen erstreckt.
ich hatte keine Lust die ganze RFC zu zitieren. Natürlich steht da auch drin, wie das mit einzeiligen Antworten geht.
Zitat
Aber das wird bei mir doch über ein "stream.ReadLine()" gelöst.
Ja, aber eben nicht so wie in der RFC gefordert. :-) So wie es in der RFC steht, bekommst du für jedes Kommando eine Antwort, deren Ende genau definiert ist. Wenn du Probleme mit Hängern hast, solltest du erstmal nur immer nur die Antworten lesen, die du erwartest.
Zitat
Ich hoffe du kannst jetzt eher in meine Problematik einsteigen.
Das tut ich schon die ganze Zeit. Mir scheint eher, dass du an deiner Lösung festhalten willst, statt so umzustellen, wie es in der RFC steht und das obwohl ich schon oben geschrieben habe, dass ich sie für ungeeignet halte.

herbivore
private Nachricht | Beiträge des Benutzers