Hallo Leute,
ich bastle im Moment ein kleines Programm, das Dateien per TCP verschicken soll. Dabei gibt es natürlich einen Server und einen Client. Der Server liest die Dateien blockweise ein (bei meinen Tests war es eine .mp3-Datei) und der Client setzt sie wieder zusammen.
Aber ich denke ich zeige euch erstmal meinen Code zum Versenden und Empfangen der Datei und erläutere danach das Problem, dass dabei auftritt (Die Code-Ausschnitte in denen der Server bzw. der Client erstellt wird und die Verbindung hergestellt wird lasse ich mal weg, da das Problem nichts damit zutun hat)
Sub zum Versenden der Datei:
Sub zum Empfangen der Datei:
Um grad nochmal zur Do-Schleife beim Empfangen zu kommen, die versucht natürlich selbst wenn die Datei schon übertragen wurde noch fleißig weiter Daten einzulesen, obwohl vom Client schon nichts mehr gesendet wird. Da ich am Server erkennen kann wann die Datei vollständig verschickt wurde, beende ich den Client dann immer gewaltsam.
Aber nun zum eigentlich Problem. Der eigentliche Transfer der Dateien funktioniert gut, die .mp3-Datei die ich zum Testen benutzt habe ist hinterher auch wiedergabefähig. Man sollte meinen, dass das ein gutes Zeichen ist, aber irgendwas läuft da trotzdem falsch. Die Beispiel-Datei war 6.445.231 Bytes groß. Die Datei die durch den Transfer erstellt wurde ist allerdings nur 6.443.008 Bytes, es fehlen also 2223 Bytes. Die MessageBox die ich zur Kontrolle beim Versenden benutzt habe, hat allerdings die vollständige Anzahl von 6.445.231 Bytes mitgezählt. Wie kann es also sein, dass 2223 Bytes anscheinend einfach verloren gehen? Die verlorenen Bytes führen zum einen dazu, dass die Dateien nachdem Transfer nicht mehr genutzt werden können, außer Mp3s, die können diese Verluste anscheinend verkraften. Außerdem macht es mir das unmöglich beim Empfangen eine Schleife zu erstellen, die beendet wird, sobald alle Bytes angekommen sind, da in keinem Fall die Anzahl der Bytes ankommen, die der Schleife mitgeteilt wird.
Habt ihr eine Idee, wie es zu diesem Verlust kommt? Ich selbst kann im Code keine Ursache dafür finden und befürchte sogar, dass die Ursache gar nicht im Code liegt. Aber vielleicht gibt es ja dennoch eine Lösung.
Ich hoffe ich hab alles so erläutert, dass ihr es theoretisch nachvollziehen könnt, wenn irgendwer es sogar praktisch nachvollziehen kann würde das bei der Ursachenfindung natürlich extrem helfen!
Schonmal vielen Dank für eure Hilfe im Voraus!
MfG
Minilulatsch
[EDIT]: Sorry, dass der Quelltext so chaotisch aussieht, ich hab mir bei den Kommentaren die ganze Formatierung zerschossen. Ich versuche mal noch da Ordnung reinzubekommen
ich bastle im Moment ein kleines Programm, das Dateien per TCP verschicken soll. Dabei gibt es natürlich einen Server und einen Client. Der Server liest die Dateien blockweise ein (bei meinen Tests war es eine .mp3-Datei) und der Client setzt sie wieder zusammen.
Aber ich denke ich zeige euch erstmal meinen Code zum Versenden und Empfangen der Datei und erläutere danach das Problem, dass dabei auftritt (Die Code-Ausschnitte in denen der Server bzw. der Client erstellt wird und die Verbindung hergestellt wird lasse ich mal weg, da das Problem nichts damit zutun hat)
Sub zum Versenden der Datei:
VB.NET-Quellcode
- Private Sub DateiVersenden(ByVal Pfad as String)
- Dim fstm As Stream = New FileStream(Pfad, FileMode.Open, FileAccess.Read)
- Dim Größe As Long = fstm.Length
- streamw.WriteLine(Größe) 'hier wird dem Client die Größe der mitgeteilt, wobei das aktuell beim Client noch nicht integriert ist (mehr dazu in der Sub zum Dateien Empfangen)
- streamw.Flush
- Dim I As Integer = 0 'dieser Int-Wert zählt die Anzahl der Bytes, die bei jedem Block versendet wird
- Dim Gesamt As Long = 0 'soll mitzählen wieviele Bytes insgesamt verschickt wurden
- Dim Puffer(1024) As Byte 'der Puffer in dem die eingelesen Bytes gespeichert werden
- Do
- I = fstm.Read(Puffer, 0, Puffer.Length) 'die Größe des aktuellen Blocks wird gespeichert und die entsprechenden Bytes in den Puffer eingelesen
- If I < Puffer.Length Then 'sollte die Anzahl der Bytes im Block kleiner sein als die normale Puffergröße, wird hier mitgeteilt, dass die entsprechende Anzahl an Bytes die in diesem Block enthalten sind verschickt werden (das habe ich eingerichtet, da der letzte Block der einzulesenden Datei in der Regel ja kleiner ist als die üblichen Blöcke)
- stream.Write(Puffer, 0, I)
- Gesamt = Gesamt + (I) 'hier werden die verschickten Bytes mitgezählt
- Exit Do 'die Do-Schleife wird dementsprechend verlassen, da, wie oben schon angesprochen, hier der letzte Block eingelesen und verschickt wurde
- End If
- stream.Write(Puffer, 0, Puffer.Length) 'sollte es sich bei einem Block nicht um den letzten handeln, wird ganz normal der Inhalt des gesamten Puffers verschickt
- Gesamt = Gesamt + (Puffer.Length) 'hier werden die verschickten Bytes mitgezählt
- Loop
- MsgBox(Prompt:=Gesamt) 'diese MessageBox habe ich zur Kontrolle eingebaut, damit mir mitgeteilt wird, wieviele Bytes insgesamt verschickt wurden
- fstm.Close()
- MsgBox(Prompt:="Abgeschlossen")
- End Sub
Sub zum Empfangen der Datei:
VB.NET-Quellcode
- Private Sub DateiEmpfangen()
- Dim writer As New BinaryWriter(File.Open(Pfad, FileMode.Create))
- Dim I As Integer = 0 'hier wird die Anzahl der Bytes im eintreffenden Block gezählt
- Dim Größe As Long = streamr.ReadLine 'hier kommt die Größe der Datei an,damit der Client weiß wie lang er Bytes empfangen soll...Spielt allerdings bei diesem Code keine Rolle, da im Moment noch zu Testzwecken die Bytes in einer Do-Schleife empfangen werden.Genau wie oben wird hier außerdem der Puffer definiert in dem die Bytes gespeichert werden
- Dim Puffer(1024) As Byte
- Do 'wie bereits gesagt, eine Do-Schleife in der die Bytes empfangen werden. Ganz einfach deswegen damit beim Testen keine Schleife benutzt wird, die evtl. zu früh beendet wird, also um sicherzugehen, dass auch wirklich alle Bytes empfangen werden. Wird später dann durch eine Schleife ersetzt, die genau soviel einlist wie nötig
- I = stream.Read(Puffer, 0, Puffer.Length) 'hier werden die Bytes eingelesen
- writer.Write(Puffer, 0, I) 'hier werden sie in die Datei geschrieben
- Loop
- End Sub
Um grad nochmal zur Do-Schleife beim Empfangen zu kommen, die versucht natürlich selbst wenn die Datei schon übertragen wurde noch fleißig weiter Daten einzulesen, obwohl vom Client schon nichts mehr gesendet wird. Da ich am Server erkennen kann wann die Datei vollständig verschickt wurde, beende ich den Client dann immer gewaltsam.
Aber nun zum eigentlich Problem. Der eigentliche Transfer der Dateien funktioniert gut, die .mp3-Datei die ich zum Testen benutzt habe ist hinterher auch wiedergabefähig. Man sollte meinen, dass das ein gutes Zeichen ist, aber irgendwas läuft da trotzdem falsch. Die Beispiel-Datei war 6.445.231 Bytes groß. Die Datei die durch den Transfer erstellt wurde ist allerdings nur 6.443.008 Bytes, es fehlen also 2223 Bytes. Die MessageBox die ich zur Kontrolle beim Versenden benutzt habe, hat allerdings die vollständige Anzahl von 6.445.231 Bytes mitgezählt. Wie kann es also sein, dass 2223 Bytes anscheinend einfach verloren gehen? Die verlorenen Bytes führen zum einen dazu, dass die Dateien nachdem Transfer nicht mehr genutzt werden können, außer Mp3s, die können diese Verluste anscheinend verkraften. Außerdem macht es mir das unmöglich beim Empfangen eine Schleife zu erstellen, die beendet wird, sobald alle Bytes angekommen sind, da in keinem Fall die Anzahl der Bytes ankommen, die der Schleife mitgeteilt wird.
Habt ihr eine Idee, wie es zu diesem Verlust kommt? Ich selbst kann im Code keine Ursache dafür finden und befürchte sogar, dass die Ursache gar nicht im Code liegt. Aber vielleicht gibt es ja dennoch eine Lösung.
Ich hoffe ich hab alles so erläutert, dass ihr es theoretisch nachvollziehen könnt, wenn irgendwer es sogar praktisch nachvollziehen kann würde das bei der Ursachenfindung natürlich extrem helfen!
Schonmal vielen Dank für eure Hilfe im Voraus!
MfG
Minilulatsch
[EDIT]: Sorry, dass der Quelltext so chaotisch aussieht, ich hab mir bei den Kommentaren die ganze Formatierung zerschossen. Ich versuche mal noch da Ordnung reinzubekommen
Dieser Beitrag wurde bereits 30 mal editiert, zuletzt von „Minilulatsch“ ()