Seite 1 von 1

Routine für "SendNetworkFile" und "ReceiveNetworkFile"

Verfasst: 11.09.2011 05:04
von Sunny
Morgen,
Ich bin grade dabei eine Routine zu schreiben, um die Befehle "SendNetworkFile" und "ReceiveNetworkFile" zu ersetzen, jetzt würde ich gerne mal eure Meinung hören, was die beste Methode dafür wäre.
Also ich hab mir folgende zwei Möglichkeiten überlegt:

1. Der Server sendet dem Client mittels "SendNetworkString" einen Befehl. Nach Verarbeitung des Befehls, sendet der Client die Größe der im Befehl angegebenen Datei, an den Server.
Der Server reserviert dann mittels "AllocateMemory" Speicherplatz der groß genug ist, um die Datei zu empfangen und dann sendet der Client mittels "SendNetworkData" die Datei.
(Das ist zwar ziemlich aufwändig aber bis jetzt hatte ich mir das so überlegt, weil die 2. Methode, über die ich gleich schreibe nicht so ganz funktionierne will)

oder

2. Der Client sendet mittels "SendNetworkData(ConnectionID, *Buffer, FileSize(File$))" die Datei und der Server empfängt die Daten der Datei mittels "ReceiveNetworkData", mit einer Buffer-Größe von z.B. 1024 Byte, in einer WhileSchleife solange bis alle Daten verarbeitet wurden.


Die 1. Methode ist zwar aufwändiger zu programmieren und braucht für die durchführung wahrscheinlich auch mehr zeit, aber mit der 2. Methode werden irgendwie immer entweder zu viel oder zu wenig Daten gesendet und die erhaltene Datei somit unbrauchbar.

Wenn ihr der meinung seit, dass die 2. Methode die bessere ist, dann würde ich noch ein CodeBeispiel senden, wie genau ich das machen würde und wo das Problem dabei liegt aber möglicherweise kennt ja jemand von euch einen besseren Weg.

Re: Routine für "SendNetworkFile" und "ReceiveNetworkFile"

Verfasst: 11.09.2011 11:45
von STARGÅTE
Die zweite Methode kannst du nicht verwenden, weil du dann bei mehreren Dateien, diese nicht mehr auseinander halten kannst.

Was du vergessen hast ist, eine Art "Identifizierung" mit einzubauen, denn du wirst wohl kaum immer nur Dateien über die Verbindung schicken oder?
Du musst also irgendwie kenntlich machen, dass die kommenden Daten für "dein eigenes" ReceiveNetworkFile bestimmt sind.

Du musst also auf jedenfall einen eigenen Header vorab senden, der zB folgende wichtige Daten enthält.
  • Identifizierung
  • Daten-/Dateilänge
  • ggf. Prüfsumme der Dateilänge, damit nicht "falscher" zu großer Speicher auf der Empfangsseite erstellt wird.
  • Prüfsumme der Daten, um nachträglich zu testen, ob alles angekommen ist.
Ach und vermeide bitte SendNetworkString, da du probleme bei Unicode/Ascii bekommst.
Wenns geht alles selbst mit Data machen.

Edit: Bezüglich der Identifizierung: Wenn du natürlich komplett dein eigenes Netzwerkprotokoll schreibst, dann reicht hier vielleicht ein Byte als Identifizierung, ansonsten müsstest du dir irgend eine große einmalige Zahl ausdenken (Quad).
Um Verwechselung auszuschließen, gibt es ja danach eh noch eine Prüfsumme für die Dateilänge

Re: Routine für "SendNetworkFile" und "ReceiveNetworkFile"

Verfasst: 11.09.2011 14:26
von Sunny
Also doch die komplexere Variante, um ehrlich zu sein hätte ich damit jetzt nicht gerechnet aber OK...

Dann werde ich (sofern meine kostbare Zeit das zulässt) im laufe der nächsten Tage mal versuchen das umzusetzen.
Danke für deine ausführliche Antwort.

Eine Frage hätte ich allerdings noch dazu, und zwar:
Warum muss ich für die Länge der Datei eine Prüfsumme erstellen?
Um die richtigkeit der später ankommenden Datei zu überprüfen ist das ja i.O. aber das auch für die Dateilänge zu machen, halte ich jetzt grade für mehr oder weniger unnötig.
Allerdings wirst du dir ja dabei schon was gedacht haben, währe nett, wenn du mir das mal erklärst.

Re: Routine für "SendNetworkFile" und "ReceiveNetworkFile"

Verfasst: 11.09.2011 14:50
von STARGÅTE
Nun ja, du hast ja selbst geschrieben, das du erst die Länge schicken willst, und dann die Daten.
Der Empfänger bekommt dann diese Länge und legt den entsprechenden Speicher an.

Wenn du nun aber die falschen Daten als "deine" Länge ausließt, dann würdest du u.u. ausversehen einfach mal 1GB speicher reservieren.
Um das nun zu verhindern sende ich bei mir immer noch eine Prüfsumme für die Länge selbst.
Und nur wenn diese für die ankommende Länge stimmt, lege ich den Speicher wirklich an.

Sicher kannst du auch einen einfachen Weg einschlagen, aber dann wirst du spätestens bei der ersten Einbindung und Verwendung deiner Routieren schnell auf Probleme/Fehler stoßen.

Re: Routine für "SendNetworkFile" und "ReceiveNetworkFile"

Verfasst: 11.09.2011 15:19
von Sunny
Achso, jetzt hab ich das verstanden.
Allerdings:
Ich hab mir überlegt 2 mal Daten zu versenden, als erstes das Protokoll mit Informationen über Client bzw. Datei und als zweites die Datei selber.

Wenn der Inhalt des Protokoll's jetzt beispielsweise so aussieht:
ClientID: 3846759
Inhalt: FileSize_19678

(das mit den Prüfsummen lasse ich jetzt mal der Einfachheit halber weg)

und ich die Daten dann Auslese und verarbeite (z.B. mittels "StringField") dann hätte ich ja die ClientID und könnte dank dem Begriff: "FileSize", hinter dem Wort "Inhalt", genau erkennen, dass es sich um die größe der Datei handelt, die der Client mit der angegebenen ID senden will. Das sollte doch eigentlich so funktionieren auch ohne eine Prüfsumme für die Dateilänge, oder sehe ich das falsch?

Re: Routine für "SendNetworkFile" und "ReceiveNetworkFile"

Verfasst: 11.09.2011 15:26
von STARGÅTE
Jo, so geht das auch, du arbeitest halt mit "Wörtern" und ich sehe, dass ich dir das wohl kaum ausreden kann^^

Aber: bildliches Beispiel: "Nur weil ich auf das Paket Äpfel drauf schreibe, müssen nicht Äpfel drin sein ;-)

Re: Routine für "SendNetworkFile" und "ReceiveNetworkFile"

Verfasst: 11.09.2011 16:15
von Sunny
Nun ja, ich hatte mir einfach nur gedacht, dass das so für mich als Programmierer etwas leichter zu bearbeiten ist, der Endnutzer wird ja nun nichts davon mitbekommen, ob in dem Protokoll ein "FieleSize" oder irgend ein MD5-Hash-Durcheinander steht. Außerdem wären bei einer eventuellen Erweiterung, die zu versendenden Eigenschaften leichter anpassbar z.B. so:
ClientID: 3846759
Aktion: SendFile
FileSize: 19678
FileName: AnyFile
FileExt: txt
MD5: ACB5A0BB8B17EADA5ACD8CED350BB856
TimeStamp: 11.09.2011 - 16:10:32


Ich denke mal so in der Art wird das dann auch später in meinem Programm aussehen, ich wollte einfach nur nochmal sicher gehen, ob es wenn ich das so mache, auch ohne Prüfsumme für die Dateigröße reibungslos funktioniert. Da sie mir in diesem Fall überflüssig erschien. Aber man wieß ja nie, ob ich möglicherweise doch noch was übersehen habe.