Speicherbereich reservieren... Welche größe?

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

Speicherbereich reservieren... Welche größe?

Beitrag von Sunny »

Ich bin grade dabei für mich und ein paar Freunden von mir, einen kleinen Messanger zu basteln, in dem man nicht nur Text, sondern auch Dateien verschicken kann.
Da ich nur ungern mit den Befehlen "SendNetworkFile / SendNetworkString" bzw "ReceiveNetworkFile" arbeite (zu viele Macken), benutze ich "SendNetworkData" bzw "ReceiveNetworkData".

Um nun z.B. eine Datei zu verschicken lese ich diese aus, reserviere einen Speicherbereich (mit "AllocateMemory"), Packe dann den Datei-Inhalt in diesen Speicherbereich und versende das mit "SendNetworkData".

Bei einer Datei, die beispielsweise eine größe von 3GB hat wäre es allerdings ziemlich ungünstig einen Speicherbereich dieser größe zu reservieren, deshalb muss ich die Datei stückchenweise, in mehreren kleinen Packeten verschicken.

Nun zu meiner eigentlichen frage:
Was wäre in diesem Fall, eine geeignette größe für die zu sendenden Packete (/ den zu reservierenden Speicherbereich)?
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 7028
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Re: Speicherbereich reservieren... Welche größe?

Beitrag von STARGÅTE »

Du willst wirklich 3GB Dateien verschicken? Dann musst du dir aber grundlegende Gedanken über die Informationserhaltung machen. Mit einfachem senden und empfangen ist das nicht getan, dann ist die datei vermutlich unvollständig.
In PB liegt die Paketgröße (wie es in der Hilfe steht) bei 64kB.
Senden kann man glaube ich 64MB mit einem rutsch.
Das wäre dann auch deine Paketgröße.
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
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Re: Speicherbereich reservieren... Welche größe?

Beitrag von ts-soft »

Sunny hat geschrieben:Bei einer Datei, die beispielsweise eine größe von 3GB hat wäre es allerdings ziemlich ungünstig einen Speicherbereich dieser größe zu reservieren
Ich weiß ja nicht, was Dein Internet-Anschluss für einen Upload hat, aber bei mir würde das "Wochen" dauern :mrgreen:
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
Benutzeravatar
RSBasic
Admin
Beiträge: 8047
Registriert: 05.10.2006 18:55
Wohnort: Gernsbach
Kontaktdaten:

Re: Speicherbereich reservieren... Welche größe?

Beitrag von RSBasic »

Glaube ich nicht, höchstens ein paar Stunden. (Bei mir circa 3 Stunden)
:mrgreen:
Aus privaten Gründen habe ich leider nicht mehr so viel Zeit wie früher. Bitte habt Verständnis dafür.
Bild
Bild
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Re: Speicherbereich reservieren... Welche größe?

Beitrag von ts-soft »

200 oder 300 MB hab ich auch schon per Skype verschickt, aber mehr? Niemals, dann lieber per FTP
auf nen Server laden und von dort laden lassen.

Wer 3 GB per Messenger verschickt hat nen Vogel oder zu viel Zeit :mrgreen:
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
Benutzeravatar
WPö
Moderator
Beiträge: 669
Registriert: 27.05.2008 12:44
Wohnort: Oberland
Kontaktdaten:

Re: Speicherbereich reservieren... Welche größe?

Beitrag von WPö »

Warum nimmste nicht eine Anfangsgröße von z.B. 16kB? Wird dreimal hintereinander der Datenblock richtig übertragen (Prüfsumme, MD5 reicht locker), vergrößerst Du den Puffer etwas (Faktor 1,2). Sobald auch nur ein Paket in einen Zeitüberlauf geht oder eine falsche Prüfsumme zustandekommt, schaltest Du wieder runter (Faktor 0,83). Minimal- und Maximalgröße müssen auch noch berücksichtigt werden.

Wennste das so machst, wie ich bei einer HTTP-Datenübertragung Amerika <-> Europa, hast Du vielleicht nur 95% der theoretisch max. Übertragungsgeschwindigkeit der Leitung, aber Datensicherheit. Da schert es mich nicht, wenn da schon wieder eine Auszeit auftritt, die eine Dateiübertragung, in einem Rutsch vorgenommen, zerschießen würde. Zusätzlich können die Daten verschlüsselt werden, je nach Wunsch.

Gruß - WPö
Ich glaube nur der Statistik, die ich selbst gefälscht habe!
Meine Netzpräsenz: WPö.de
PB5.31 auf LMDE und Pentium T7200 2,00GHz, 4GB DDR2, ATI X1400.
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 7028
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Re: Speicherbereich reservieren... Welche größe?

Beitrag von STARGÅTE »

Also für meine Leitung (20KB/s Upload) brauchen 3GB ca. 42h.

Es gibt mit Sicherheit schnellere Leitungen, trotzdem verschickt man nicht einfach mal so 3GB durchs Netz.

Fest steht, der Ausgangspuffer kann nur eine gewisse Datenmenge aufnehmen.
Nach einigen Test, liefert bei mir SendNetworkData() bis zu einer größe von 128MB ein Erfolgsergebnis.
Das heißt, erst wenn diese 128MB rausgeschickt wurden, kann ich erst wieder ein weites SendNetworkData() erfolgreich ausführen.
Der Erfolg von SendNetworkData() sagt mir aber auch nur das die Daten zum Ausgangspuffer geschickt wurde, nicht das sie ihr wahres Ziel erreicht haben.

Damit du also nicht unnötig oft SendNetworkData() aufrufen musst, um zu testen ob es geht, musst du eh eine Art Rückmeldung vom anderen programmieren, der sich alle 10MB oder so bemerkbar macht.
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: Speicherbereich reservieren... Welche größe?

Beitrag von Sunny »

Damit du also nicht unnötig oft SendNetworkData() aufrufen musst, um zu testen ob es geht, musst du eh eine Art Rückmeldung vom anderen programmieren, der sich alle 10MB oder so bemerkbar macht.
Naja, ich sende ja nicht nur den Datei-Inhalt, sondern eine Art Protokoll das ungefähr so aussieht:
Die ersten 8 Byte des Speicherbereichs enthalten eine Variable, mit deren Wert gecheckt wird, ob es sich um eine Datei oder um Text handelt.
Die 2. 8 Byte enthalten die Nummer des gesendeten Packets (wenn beispielsweise bereits 8 Packete versendet wurden, dann erhält das nächste Packet die Nummer 9)
Die 3. 8 Byte enthalten die maximale Anzahl der Packete.
Die 4. 8 Byte enthält die größe des zu sendenden Inhalts
Danach wird ein Weiterer Speicherbereich von der größe des Inhalts reserviert und dieser Inhalt dann da "reingepackt" ^^
Das alles zusammen wird dann versendet und dann könnte ich ja jedes mal die aktuelle Packet-Nummer mit der vorigen vergleichen, um zu checken, ob auch wirklich nichts übersprungen wurde und alles angekommen ist.

P.S.: Ich habe auch noch vor eine Prüfsumme des zu sendenden Inhalts mit zu verschicken, um zu überprüfen, ob auch wirklich das angekommen ist, was versendet wurde.
Benutzeravatar
PMV
Beiträge: 2765
Registriert: 29.08.2004 13:59
Wohnort: Baden-Württemberg

Re: Speicherbereich reservieren... Welche größe?

Beitrag von PMV »

Euch ist schon klar, das TCP bereits die Rolle mit der Prüfsumme und
dem sicherstellen, das alles in der richtigen Reihenfolge ist übernimmt?

Die extra Prüfsumme ist nötig um gegen z.B. Man-In-The-Middle attacken
reagieren zu können. SendNetworkData() gibt zurück, wie viel Daten
tatsächlich versendet wurden und darauf muss reagiert werden. Nur wenn
UDP verwendet wird, muss selbst sorge getragen werden, dass die
Daten richtig ankommen. UPD verwendet man aber ja auch nur, wenn
das nicht so wichtig ist.

Es reicht also, die Datei in 64KB-Blöcke zu versenden und jedes mal,
wenn SendNetworkData() einen kleineren Wert zurück gibt, die aus-
stehenden Daten noch mal zu versenden. :wink: Zu beginn noch
die tatsächliche Dateilänge senden und ne Prüfsumme für die gesamte
Datei.

Auf der Empfängerseite einfach so lange lesen, wie Daten noch ausstehen
und alles ankommende direkt in eine echte Datei schreiben. Nach fertig-
stellung der Downloads die Prüfsumme gegen prüfen und das wars.

Und ganz wichtig. Die versendeten Blöcken kommen im regelfall nicht
als genau solche Blöcke beim Empfänger an. Also nicht davon ausgehen,
das 64KB Blöcke beim Empfänger ankommen und stupide alles verwerfen,
wenn dem mal nicht so ist. Einfach weiter lesen. <)

MFG PMV
alte Projekte:
TSE, CWL, Chatsystem, GameMaker, AI-Game DLL, Fileparser, usw. -.-
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 7028
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Re: Speicherbereich reservieren... Welche größe?

Beitrag von STARGÅTE »

PMV hat geschrieben:SendNetworkData() gibt zurück, wie viel Daten
tatsächlich versendet wurden und darauf muss reagiert werden.
Nein, so ist es eben nicht (wie ich schon am Anfang erklärt habe).
SendNetworkData() kopiert nur meinen Speicher in den Ausgangspuffer Vom Netzwerk.
Das Ergebnis gibt mir dann nur an, wie viele Bytes im Ausgangspuffer landeten.

SendNetworkData() wartet also nicht darauf, dass die Daten wirklich beim anderen angekommen sind bzw. dort auch gelesen wurden.
Klar stellt das TCP-Protokoll sicher, dass der Datenverkehr informationserhaltend ist,
trotzdem weiß der sendende nicht ob seine Daten auf der anderen Seite angekommen sind.
Wie auch, sonst müsste ja jedes SendNetworkData() u.u. mehrere Sekunden warten und somit die Programmausführung anhalten.
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
Antworten