![]() |
Indy10 Write&ReadStream TArray<String>
Ich versuche, String-arrays dynamischer Laenge deklariert mit TArray<String> mit indy10 in Delphi10Seattle vom Server zum Client schicken zu lassen.
Ich habe mich fuer die Variante mit automatischer StreamLength Uebermittlung entschieden: Type
Code:
Server
TTestRecord = TArray<String>;
Code:
Client
procedure TStatusForm.IdTCPUpdateCommands;
var S: String; I: Integer; AStream: TMemoryStream; ALength: Integer; AContext: TIdContext; AClientList: TList; ATestRecord: TTestRecord; begin SetLength(ATestRecord, 3); ATestREcord[1] := 'Tester'; if not Assigned(IdTCPServer1.Contexts) then Exit; try AClientList := IdTCPServer1.Contexts.LockList; for I:=0 to AClientList.Count-1 do begin AContext := TIdContext(AClientList[I]); try if AContext.Connection.IOHandler.InputBufferIsEmpty then AContext.Connection.IOHandler.CheckForDataOnSource(0); while not AContext.Connection.IOHandler.InputBufferIsEmpty do begin S := AContext.Connection.IOHandler.ReadLn; if S = 'SendMeTheRecord' then begin try AStream := TMemoryStream.Create; ALength := Length(ATestRecord); AStream.Position := 0; AStream.Write(ALength, SizeOf(Integer)); AStream.Write(ATestRecord[0], SizeOf(ATestRecord[0])*ALength); AContext.Connection.IOHandler.Write(AStream, 0, True); // mit schreiben der Laenge finally AStream.Free; end; end; end; except on E: Exception do AContext.Connection.Disconnect; end; end; finally IdTCPServer1.Contexts.UnlockList; end; end;
Code:
Wenn ich mein TestRecord auf TArray<Integer> ummuenze, geht alles. Ein Testwert auf array[1] kommt an.
procedure TTransfer2Frame.Button1Click(Sender: TObject);
var AStream: TMemoryStream; ALength: Integer; ASize: Integer; ATestRecord: TTestRecord; begin TCP2Frame.IdTCPClient1.IOHandler.WriteLn('SendMeTheRecord'); try AStream := TMemoryStream.Create; TCP2Frame.IdTCPClient1.IOHandler.ReadStream(AStream, -1, False); // mit Laengenangabe AStream.Position := 0; AStream.Read(ALength, SizeOf(Integer)); SetLength(ATestRecord, ALength); AStream.Read(ATestRecord[0], SizeOf(ATestRecord[0])*ALength); finally AStream.Free; end; end; Mit den Strings verbockt er es aber. Es kommt entweder chinesischer Zeichen-Salat statt "Tester" oder "Nicht verfuegbarer Wert". Warum passiert das und wie kann ich die Situation elegant loesen? |
AW: Indy10 Write&ReadStream TArray<String>
Hat sich erledigt.
Eigentlich voellig klar: String ist selbst ein dynamisches array of Char. Solange man keine fixen Laengen verwendet (TArray<String[30]>), muesste man fuer jeden String individuell die Laenge uebermitteln, wie in meinem Beispiel eine Ebene hoeher fuer Length(TArray<String>) bereits geschehen. Die ganze Serialisier-Story in delphi habe ich noch nich wirklich befriedigend geloest. Egal ueber welche Streams ich meine Daten jagen will, immer laeuft es darauf hinaus, alles undynamisch zu behandeln. Schade. Ich kann nicht recht glauben, dass jeder andere Indy-user nur fixed-length Strings uebertraegt. Oder deren Struktur so simpel ist, dass sie immer nur einen einzelnen String versenden, dessen Laenge sich dann aus dem IOhandler ergibt. In der Praxis ist es doch zumeist so: Du hast eine ObjectList, die ein dynamisches Array of Record enthaelt, der wiederum... und dann willst Du den ganzen Kaese ueber TCP/IP uebermitteln. Ich kann doch nicht der einzige mit dem Problem sein, keinen Bock darauf zu haben, in jeder logischen hierarchie-Ebene zig Laengen von dynamischen Typen einzeln abzugurken. Wie macht ihr das denn? |
AW: Indy10 Write&ReadStream TArray<String>
Der Server geht durch alle Connections und schaut ob Nachrichten vom Client empfangen wurden :gruebel:
Macht man das nicht normalerweise in der OnExecute Methode? Diese wird ja im speziellen Threadkontext der Connection ausgeführt, so dass man sich das LockList Gedöns sparen kann und ohne Schleife auskommt. |
AW: Indy10 Write&ReadStream TArray<String>
Zitat:
Code:
Ja, stimmt. Wenn ich die Funktion nicht woanders noch ohne AContext aufrufen wuerde, koennte ich mir die Schleife sparen.
procedure TStatusForm.IdTCPServer1Execute(AContext: TIdContext);
begin IdTCPUpdateCommands; end; |
AW: Indy10 Write&ReadStream TArray<String>
Zitat:
Dabei wird alles in einen strukturierten String geschrieben, dieser hat eine bestimmte Länge. In der Praxis (Protokolle wie AMQP oder MQTT) baut man dann noch einen Block mit Zusatzdaten davor, der aber protokollspezifisch ist und mit bekannten Längen und Trennzeichen arbeitet. Die Payload (Body) ist dann ein Binärblock oder eben ein z.B. nullterminierter String. |
AW: Indy10 Write&ReadStream TArray<String>
Zitat:
Ich bin schon eine ganze Weile lang auf der Suche nach einem brauchbaren XML-serializer, finde aber meist schon tote Projekte. Wenn ich Dich richtig verstehe, sagst du, es gaebe ein Mittel, mit dem ich dynamische Typen (arrays of records of strings o.ae.) einfach nach XML serialisieren kann. Wie? |
AW: Indy10 Write&ReadStream TArray<String>
Zitat:
![]() |
Alle Zeitangaben in WEZ +1. Es ist jetzt 12:19 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