Einzelnen Beitrag anzeigen

Benutzerbild von Aphton
Aphton

Registriert seit: 31. Mai 2009
1.198 Beiträge
 
Turbo Delphi für Win32
 
#11

AW: Indy 10 / streams via tcp ip senden

  Alt 24. Nov 2011, 08:48
Änder mal das hier, auf folgendes um:
Delphi-Quellcode:
  AClient.IOHandler.Write(AStream, StreamSize);
->
  AClient.IOHandler.Write(AStream.Memory^, StreamSize);
Und definiere AStream im Rumpf als TMemoryStream (sonst hast du keine "Memory" Property, auf die du schön zugreifen kannst)

Noch ne kleine, jedoch sehr wichtige Bemerkung:
Schickst du 10 kb ab, heißt es nicht dringend, dass 10 kb auch ankommen.
Kann sein, dass zuerst 2 kb ankommen, dann 5 kb, dann 1 kb und letzendlich 2 kb.

DU musst dir ne Struktur überlegen, die damit klar kommt.

Am besten nen globalen Stream anlegen, der alle ankommenden Daten puffert. Und aus dem Puffer extrahiert er ganze Datensätze.

Senden: 5 kb (Bild), 10 kb (Audio), ... (15 kb)
Puffer ->
Empfängt: 2kb, 5kb, nix, 3kb, 4kb, 1kb, ... (15 kb)

Jedesmal nach dem empfangen guggst du nach, ob ein ganzer Datensatz (Bild = 5kb, Audio = 10kb) da ist.
Dh nach dem ersten Empfangen hast du 2 kb, du liest die ersten 4 Bytes aus (Size) und guggst, ob die Größe des Puffers - 4 Bytes diesem Wert entspricht (oder größer ist), falls nicht, ist noch kein ganzer Datensatz da.
Falls ja, dann extrahierst du diesen Datensatz und arbeitest halt damit weiter. Puffern vergisst du im Hintergrund auch nicht. Muss schön weiterlaufen.
Wichtig ist noch, dass du die Daten, die du extrahiert hast, aus dem Puffer löschen solltest, da sonst dieser riesengroß wird und deine Anwendung crasht.

EDIT:
In Windows ist es ja so, dass man nur eine bestimmte Größe von Daten abschicken kann. Der maximale Wert (der zuerst gesetzt werden muss) ist 64 kb. Standardmäßig sinds (glaube ich) nur 8 kb (8192 b).
Deshalb würde ich WIEDER nen Puffer empfehlen, in die du die Daten, die du abschicken willst, reinpufferst. Vorallem auch weil man nicht wirklich immer Daten in dieser Größe abschicken kann, weil Windows intern auch noch puffert und die Daten erst später abschickt -> ist dieser Puffer voll, wird Send() nicht funktionieren.

Daten: 10 mb
Sendegröße: 8kb
Senden: 8 kb, 4 kb, 7 kb, 8 kb, 8 kb
Jedesmal nach dem Senden muss der Positionszeiger im Sendepuffer richtig gesetzt werden -> Position = Position + BytesSent

So habe ich das einmal realisiert und das ganze in ne Komponente gepackt.

Edit:
Ich weiß nicht, ob das Indy intern macht; ich habe nur mit den Standard TServerSocket / TClientSocket Komponenten gearbeitet (die imho nicht der Indy Komponentensammlung angehören)
das Erkennen beginnt, wenn der Erkennende vom zu Erkennenden Abstand nimmt
MfG

Geändert von Aphton (24. Nov 2011 um 09:46 Uhr)
  Mit Zitat antworten Zitat