Einzelnen Beitrag anzeigen

hzzm

Registriert seit: 8. Apr 2016
103 Beiträge
 
Delphi 10 Seattle Professional
 
#1

Indy10 Write&ReadStream TArray<String>

  Alt 17. Mai 2017, 11:44
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:
  TTestRecord = TArray<String>;
Server
Code:
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;
Client
Code:
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;
Wenn ich mein TestRecord auf TArray<Integer> ummuenze, geht alles. Ein Testwert auf array[1] kommt an.
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?

Geändert von hzzm (17. Mai 2017 um 11:49 Uhr) Grund: inhaltlich korrigiert
  Mit Zitat antworten Zitat