AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Netzwerke Delphi Indy Server -> Client Stream
Thema durchsuchen
Ansicht
Themen-Optionen

Indy Server -> Client Stream

Ein Thema von schwa226 · begonnen am 21. Jan 2010 · letzter Beitrag vom 21. Jan 2010
Antwort Antwort
schwa226

Registriert seit: 4. Apr 2008
400 Beiträge
 
#1

Indy Server -> Client Stream

  Alt 21. Jan 2010, 08:24
Hi,

habe hirzu ein Frage wenn ich einen Stream vom Server zum Client schicken will.

Der Client hat einen eigenen Thread wo er mit InputBufferIsEmpty überprüft ob Daten vorhanden sind.

Sind nun Daten vorhanden speichert er sie in einem Stream (Server schickt auch einen Stream):
Delphi-Quellcode:
MyIdTCPClient.IOHandler.InputBufferToStream(fileStream);
EventCallbackProcedure(fileStream); //Send to MainForm
Nun habe ich das Problem, dass der Stream den der Server schickt z.B . 22KB groß ist.

Der Client bekommt aber nur z.B. 11KB. Somit ist der Stream noch nicht vollständig.

Wenn ich es so versuche:
Delphi-Quellcode:
            repeat
              MyIdTCPClient.IOHandler.InputBufferToStream(fileStream);
              Sleep(10);
            until MyIdTCPClient.IOHandler.InputBufferIsEmpty;
            EventCallbackProcedure(fileStream); //Send to MainForm
Kommt mein Stream zerstückelt an:
Zitat:
Stream received, size: 11060
Stream received, size: 13339
Wie kann man das am besten machen?
Delphi 2010, Update 4 & 5
  Mit Zitat antworten Zitat
schwa226

Registriert seit: 4. Apr 2008
400 Beiträge
 
#2

Re: Indy Server -> Client Stream

  Alt 21. Jan 2010, 09:27
Ok, habe es nun so gelöst:

Delphi-Quellcode:
        if not MyIdTCPClient.IOHandler.InputBufferIsEmpty then
        begin

          if StreamComplete then
          begin

            fileStream := TMemoryStream.Create;
            TempStream := TMemoryStream.Create;

            MyIdTCPClient.IOHandler.InputBuffer.ExtractToStream(TempStream);
            TempStream.Seek(0, soFromBeginning);
            TempStream.Read(StreamSize, SizeOf(Int64));

            fileStream.CopyFrom(TempStream, TempStream.Size - SizeOf(Int64));

            if fileStream.Size >= StreamSize then
            begin
              EventCallbackProcedure(fileStream);
              FreeAndNil(TempStream);
              FreeAndNil(fileStream);
              StreamComplete := True;
            end
            else
              StreamComplete := False;

          end
          else begin
            TempStream.Clear;
            MyIdTCPClient.IOHandler.InputBuffer.ExtractToStream(TempStream);
            TempStream.Seek(0, soFromBeginning);
            fileStream.CopyFrom(TempStream, TempStream.Size);

            if fileStream.Size >= StreamSize then
            begin
              EventCallbackProcedure(fileStream);
              FreeAndNil(TempStream);
              FreeAndNil(fileStream);
              StreamComplete := True;
            end;

          end;
        end;
Delphi 2010, Update 4 & 5
  Mit Zitat antworten Zitat
Benutzerbild von DataCool
DataCool

Registriert seit: 10. Feb 2003
Ort: Lingen
909 Beiträge
 
Delphi 10.3 Rio
 
#3

Re: Indy Server -> Client Stream

  Alt 21. Jan 2010, 09:54
Hi schwa226,

das sollte aber auch eleganter/kürzer gehen.
Wie schickst Du den Stream den beim Server zum Client ? Gestückelt oder in einem Stück ?
Meiner Meinung ist es am besten und einfachsten so:

Delphi-Quellcode:
Var ms : TMemoryStream;
begin
  // ...
  AContext.Connection.Socket.Write(ms,0,true); // <--- das true sorgt dafür das die Größe des Stream am Anfang geschrieben wird
  // ...
Im Client würde ich dann wie folgt vorgehen :
Delphi-Quellcode:
Var ms : TMemoryStream;
begin
  // ...
  if not myTcpClient.Socket.InputBufferIsEmpty then

    myTcpClient.Socket.ReadStream(ms); // = myTcpClient.Socket.ReadStream(ms, -1, false)
    // When AByteCount contains the value -1, the amount of data to read from the IOHandler is determined either by reading the byte count from the IOHandler
    // or by reading data until the connection is closed by the peer.
Das sollte absolut ausreichen, So funktioniert es auf jeden FAll bei in einigen Anwendungen

Greetz Data
Der Horizont vieler Menschen ist ein Kreis mit Radius Null, und das nennen sie ihren Standpunkt.
  Mit Zitat antworten Zitat
schwa226

Registriert seit: 4. Apr 2008
400 Beiträge
 
#4

Re: Indy Server -> Client Stream

  Alt 21. Jan 2010, 14:25
Super Danke!

Ich schicke einen ganzen Stream zum Client. Da ist alles zusammengepackt.

Werde ich ausprobieren!

Nun habe ich aber schon wieder ein Problem:
Zuerst hatte ich 1 Byte vom Client zum Server als Command geschickt.
Dies habe ich mit
Command := AContext.Connection.IOHandler.ReadByte; in der Execute Methode gelesen. Hat auch super funktioniert.

Nun möchte ich aber auch Strings senden.
Also habe ich das Command und den String in einen Stream gepackt und diesen an den Server geschickt.
Nun bleibt wir der Server aber hier stehen:
AContext.Connection.IOHandler.ReadStream(ReceivedStream); Wieso geht das jetzt nicht das ich einen Stream vom Client zum Server schicke?
Delphi 2010, Update 4 & 5
  Mit Zitat antworten Zitat
Benutzerbild von DataCool
DataCool

Registriert seit: 10. Feb 2003
Ort: Lingen
909 Beiträge
 
Delphi 10.3 Rio
 
#5

Re: Indy Server -> Client Stream

  Alt 21. Jan 2010, 14:38
Hi schwa226,

- Du darfst beim Senden eines Streams Paramter beim Write vergessen:
Write(ms,0,true); // <--- das true sorgt dafür das die Größe des Stream am Anfang geschrieben wird - Du must wenn Du einen String in einem Stream schreibst vorher die Größe des Strings in den Stream schreiben sonst
bekommst Du das ganze nicht mehr sauber auseinander.

Zeig mal bitte wie Du beim Client das Commando und einen String in den Stream schreibst
und wie Du dann den Stream verschickst.

Greetz Data
Der Horizont vieler Menschen ist ein Kreis mit Radius Null, und das nennen sie ihren Standpunkt.
  Mit Zitat antworten Zitat
schwa226

Registriert seit: 4. Apr 2008
400 Beiträge
 
#6

Re: Indy Server -> Client Stream

  Alt 21. Jan 2010, 15:13
Irgendwie geht es jetzt gar nicht mehr...

Ich sende vom CLient das:
MyIdTCPClient.IOHandler.Write(Byte(Msg.LParam)); Für Write schlägt er mir noch vor:
Length und Offset.

Wenn ich jedoch das mache bekomme ich einen Fehler beim kompilieren:
MyIdTCPClient.IOHandler.Write(Byte(Msg.LParam), 1, 0); E2250

Mache ich es wie oben kommt was an beim Server jedoch bleibt es in der Zeile:
Command := AContext.Connection.IOHandler.ReadByte; stehen.

Vor noch ~ 2 Stunden ist es über die Zeile rübergelaufen und hat weiter gemacht und das Command ausgewertet.
Warum geht das nun nicht mehr?

ManOMan!
Delphi 2010, Update 4 & 5
  Mit Zitat antworten Zitat
Benutzerbild von DataCool
DataCool

Registriert seit: 10. Feb 2003
Ort: Lingen
909 Beiträge
 
Delphi 10.3 Rio
 
#7

Re: Indy Server -> Client Stream

  Alt 21. Jan 2010, 15:35
Hi,

ich rede vom verschicken eines Streams!
Du schreibst im Moment nur ein Byte, wobei Msg.LParam wahrscheinlich auch kein Byte ist!!!

Ich gehe bei meinem Lösungsansatz davon aus, das Du lokal einen Stream erzeugst in diesen Stream
Dein Kommando, die Länge Deines Strings und den String selber schreibst.

Erst danach wird dieser Stream(höchstwahrscheinlich ein MemoryStream) mit denen von mir oben beschriebenen Methoden verschickt/empfangen.

Greetz Data
Der Horizont vieler Menschen ist ein Kreis mit Radius Null, und das nennen sie ihren Standpunkt.
  Mit Zitat antworten Zitat
schwa226

Registriert seit: 4. Apr 2008
400 Beiträge
 
#8

Re: Indy Server -> Client Stream

  Alt 21. Jan 2010, 16:26
Hab's nun wieder hinbekommen!

War nur ein kleiner Fehler.

Msg.LParam ist sicher nur 1 Byte, da ich Konstanten von 0-FF übergebe.

Egal...

Wenn ich nun den Stream mit (Stream,0 ,True) verschicke kommt dieser auch an.

Nun habe ich aber das Problem:
Delphi-Quellcode:
  ReceivedStream.Read(Command, 1);
  ReceivedStream.Size;
Die Size ist 1 Byte, das ist OK.
Jedoch kommt bei Read der Wert 3 ins Command.

Wenn ich es so mache:
CopyMemory(@Command, ReceivedStream.Memory, 1); kommt der richtige Wert 35 ins Command.

EDIT:
ReceivedStream.Seek(0, soFromBeginning);
Musste den Stream noch zurücksetzen!

Danke!
Delphi 2010, Update 4 & 5
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 11:04 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz