![]() |
Indy Server -> Client Stream
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:
Nun habe ich das Problem, dass der Stream den der Server schickt z.B . 22KB groß ist.
MyIdTCPClient.IOHandler.InputBufferToStream(fileStream);
EventCallbackProcedure(fileStream); //Send to MainForm Der Client bekommt aber nur z.B. 11KB. Somit ist der Stream noch nicht vollständig. Wenn ich es so versuche:
Delphi-Quellcode:
Kommt mein Stream zerstückelt an:
repeat
MyIdTCPClient.IOHandler.InputBufferToStream(fileStream); Sleep(10); until MyIdTCPClient.IOHandler.InputBufferIsEmpty; EventCallbackProcedure(fileStream); //Send to MainForm Zitat:
|
Re: Indy Server -> Client Stream
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; |
Re: Indy Server -> Client Stream
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:
Im Client würde ich dann wie folgt vorgehen :
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 // ...
Delphi-Quellcode:
Das sollte absolut ausreichen, So funktioniert es auf jeden FAll bei in einigen Anwendungen ;-)
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. Greetz Data |
Re: Indy Server -> Client Stream
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
Delphi-Quellcode:
in der Execute Methode gelesen. Hat auch super funktioniert.
Command := AContext.Connection.IOHandler.ReadByte;
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:
Delphi-Quellcode:
Wieso geht das jetzt nicht das ich einen Stream vom Client zum Server schicke?
AContext.Connection.IOHandler.ReadStream(ReceivedStream);
:wiejetzt: |
Re: Indy Server -> Client Stream
Hi schwa226,
- Du darfst beim Senden eines Streams Paramter beim Write vergessen:
Delphi-Quellcode:
- Du must wenn Du einen String in einem Stream schreibst vorher die Größe des Strings in den Stream schreiben sonst
Write(ms,0,true); // <--- das true sorgt dafür das die Größe des Stream am Anfang geschrieben wird
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 |
Re: Indy Server -> Client Stream
Irgendwie geht es jetzt gar nicht mehr...
Ich sende vom CLient das:
Delphi-Quellcode:
Für Write schlägt er mir noch vor:
MyIdTCPClient.IOHandler.Write(Byte(Msg.LParam));
Length und Offset. Wenn ich jedoch das mache bekomme ich einen Fehler beim kompilieren:
Delphi-Quellcode:
E2250
MyIdTCPClient.IOHandler.Write(Byte(Msg.LParam), 1, 0);
Mache ich es wie oben kommt was an beim Server jedoch bleibt es in der Zeile:
Delphi-Quellcode:
stehen.
Command := AContext.Connection.IOHandler.ReadByte;
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! |
Re: Indy Server -> Client Stream
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 |
Re: Indy Server -> Client Stream
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:
Die Size ist 1 Byte, das ist OK.
ReceivedStream.Read(Command, 1);
ReceivedStream.Size; Jedoch kommt bei Read der Wert 3 ins Command. Wenn ich es so mache:
Delphi-Quellcode:
kommt der richtige Wert 35 ins Command.
CopyMemory(@Command, ReceivedStream.Memory, 1);
EDIT: ReceivedStream.Seek(0, soFromBeginning); Musste den Stream noch zurücksetzen! Danke! |
Alle Zeitangaben in WEZ +1. Es ist jetzt 22:46 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz