Routine für "SendNetworkFile" und "ReceiveNetworkFile"

Anfängerfragen zum Programmieren mit PureBasic.
Benutzeravatar
Sunny
Beiträge: 290
Registriert: 19.02.2009 06:02

Routine für "SendNetworkFile" und "ReceiveNetworkFile"

Beitrag 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.
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 7031
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

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

Beitrag 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
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
Benutzeravatar
Sunny
Beiträge: 290
Registriert: 19.02.2009 06:02

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

Beitrag 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.
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 7031
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

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

Beitrag 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.
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
Benutzeravatar
Sunny
Beiträge: 290
Registriert: 19.02.2009 06:02

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

Beitrag 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?
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 7031
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

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

Beitrag 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 ;-)
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
Benutzeravatar
Sunny
Beiträge: 290
Registriert: 19.02.2009 06:02

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

Beitrag 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.
Antworten