C# NetworkStream verändert das Byte-Array

Zhen

Lt. Junior Grade
Registriert
Aug. 2009
Beiträge
299
Hallo Leute,
ich spiele mich momentan bisschen mit dem NetworkStream in C# rum :D

Allerdings bin ich da auf etwas aufmerksam geworden das irgendwie komisch ist...
Also es ist so, wenn ich z.B. ein Bytearray habe das 10240 Bytes groß ist und es verschicken will (aber nicht alles auf einmal sondern z.B. in einer Schleife immer nur 1024 Bytes)

Beispiel:
PHP:
int sentBytes = 0;
int bytesToSend = 1024;
int totalBytes = puffer.Length //entspricht 10240 Bytes

do {
  networkStream.Write(puffer, 0, bytesToSend);
  sentBytes += bytesToSend;
while(sentBytes < totalBytes);

auf der anderen Seite empfange ich die Bytes genauso in einer Schleife. Gelesen werden auch immer 1024 Bytes.

Nun ist aber das Problem, dass z.B. sich der Hashwert dieser Bytes ändert und wenn ich sie verschlüsselt hatte und sie auf der anderen Seite wieder entschlüsseln will kommt folgende Exception:

Code:
CryptographicException
Zeichenabstände sind ungültig und können nicht entfernt werden.

Die Exception und das Problem kann umgangen werden, wenn ich z.B. auf der SENDER-Seite folgendes schreibe:

PHP:
networkStream.Write(puffer, 0, puffer.Lenght);

jedoch ist das nicht unbedingt die beste Lösung, wenn ich z.B. einen Fortschrittsbalken einbauen will oder sowas... :(

Hoffe ihr kennt das eine Lösung
 
Öhm du schickst auch immer nur die ersten 1024 Bytes.

Code:
networkStream.Write(puffer, sentBytes, bytesToSend);

So läuft das aber auf eine OutOfBounds-Exception heraus, wenn die Gesamtlänge der Nachricht sich nicht gerade durch 1024 teilen lässt.
 
Zuletzt bearbeitet:
AAAAAAHHHHHHH... mei... jetzt komm ich mir irgendwie total dämlich vor -_-"

:D :D :D

Ja für den Fall mit den 1024 Bytes hab ich schon vorsorge getroffen (die hab ich nur hier nicht aufgelistet, weil ich da extra ein Beispiel genommen habe das sich durch 1024 Bytes teilen lässt ;-) )

Ich hab aber wirklich patu den Fehler mit den sentBytes nicht gesehen. Vielen, vielen Dank... :)

Dann sollte es ja jetzt funktionieren, probier ich gleich mal aus ;-)
 
Das Problem könnte er aber umgehen

Code:
if((totalBytes-sentBytes)<bytesToSend){
   tmpBytesToSend = (totalBytes-sentBytes);
}
else {
  tmpBytesToSend = bytesToSend;
}
networkStream.Write(puffer, sentBytes, tmpBytesToSend);

Oder habe ich da gerade einen Denkfehler?
 
ne so ähnlich habe ich es auch :)

PHP:
if ((puffer.Length - sentBytes) < bytesToSend)
	bytesToSend = (puffer.Length - sentBytes);
Ergänzung ()

Perfekt, habs gerade getestet, es funktioniert alles wie es soll :)

Hab mir außerdem die Empfänger-Seite nochmals angeguckt was ich mir da zusammengecodet habe und witziger Weise war es dort richtig xD :D :D

PHP:
int receivedBytes = 0;
int bytesToReceive = 1024;

do {
  receivedBytes += networkStream.Read(puffer, receivedBytes, bytesToReceive);
} while(receivedbytes < puffer.Lenght);


Also manchmal sieht man echt den Wald vor lauter Bäumen nicht :D

Danke nochmals :)
 
Doofe Frage, wieso schickst du, was du senden willst nicht auf einmal? Also warum muss es auf 1024er-Häppchen gesplittet werden?

und eleganter finde ich:
Code:
bytesToSend = Math.Min(totalBytes - sentBytes, puffer.Length);
 
Zuletzt bearbeitet:
Ich schick es deswegen nicht alles auf einmal, weil ich einen Fortschrittsbalken anzeigen wollte. ;-)

Wenn der User jetzt eine 130 MB Datei schickt, dann soll er ja wenigstens wissen wie weit diese bereits versendet ist. Genauso soll er den Download Pausieren und Fortsetzen können.

Woran ich momentan verzweifle ist, dass ich nicht weiß wie ich den Transfer "abbrechen" könnte ohne gleich die ganze Verbindung zu trennen... :-/
Ergänzung ()

Also falls der user jetzt z.B. ne falsche Datei verschickt hat, dann woll er den Transfer abbrechen können, aber irgendwie hab ich grad keine Idee wie ich das anstellen sollte.... :(
 
Du kannst den Stream ja schließen, aber wie teilst du deinem Gegenüber mit, dass er die bereits gesendeten Daten verwerfen kann? Da bietet sich meines Erachtens nach eine Steuerverbindung an wie bei FTP. Diese kann über festgelegte Kommandos den Datenverkehr steuern, starten, stoppen, pausieren usw.
 
ist vielleicht jetzt eine dumme Frage, aber... wie wäre den so eine Steuerverbindung realisierbar?

Da bräuchte ich ja MINDESTENS 2 TcpClients (2 NetworkStreams), weil ich ja Daten empfange UND sende!
Das heißt, bei dem einen sende/empfange ich Befehle und anschließend die Daten "zum Client" und beim anderen sende/empfange ich Befehle und anschließend die Daten "zum Host".

Oder bin ich da auf dem falschen Weg?!

Hast du vielleicht Tipps/Ratschläge/Tutorials oder so? :)

Wäre echt Klasse und Danke schonmal im Vorraus.
 
Lies dich mal in FTP ein. Die Steuerleitung übermittelt nur Befehle, die Datenleitung nur Daten. Über die Befehle weiß jede Seite, ob sie Daten empfangen oder senden soll, die Übertragung gestoppt wurde oder sonstwas. Es gibt mit Sicherheit auch C# Implementierungen einer FTP Kommunikation. Ich hab das mal im Studium mit Java gebaut.
 
Ok vielen Dank für die Tipps :)

Werd mich da mal erkundigen und reinlesen. Hoffentlich löst es meine Probleme :D
 
dem muss ich doch glatt trockenen programmierer humor hinzufügen mit der antwort:

wär auch schlimm wenns nicht so wär :D

lg
 
Problem gelöst (glaube ich :D ).
Ne weile nicht daran gesessen, aber heute nochmal umgeschrieben und verbessert.

Muss nur noch testen ob alles auch so funktioniert ;-)
 
Zurück
Oben