Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Netzwerke (https://www.delphipraxis.net/14-netzwerke/)
-   -   Delphi Indy 10 - Protokoll richtig aufbauen (https://www.delphipraxis.net/145187-indy-10-protokoll-richtig-aufbauen.html)

Dragon27 25. Dez 2009 18:09


Indy 10 - Protokoll richtig aufbauen
 
Hallo,

ich bin gerade dabei eine App mit Indy zu schreiben. Nun bin ich am Punkt Protokoll angelangt und wollte fragen ob es den praktikabel, sicher und schön ist einen Record zu schicken?

Delphi-Quellcode:
type TProtokoll=record
Befehl:String;
Ter1:String;
Ter2:String;
Ter3:String;
Ter4:String;
BDaten:Boolean;
end;
Ich würde das ganze gerne relativ offen lassen um auch Dateien schicken zu können.... Ist mein Ansatz gut? Habt Ihr einen besseren?

Danke!

Namenloser 25. Dez 2009 18:13

Re: Indy 10 - Protokoll richtig aufbauen
 
Du kannst Strings nicht so versenden, weil der Record wegen der variablen Länge der Strings nur Pointer enthält. Du würdest also am ende einfach nur Poinetr hin- und herschicken, mit denen der Empfänger nichts anfangen kann.

Dragon27 25. Dez 2009 18:15

Re: Indy 10 - Protokoll richtig aufbauen
 
Sprich ich muss eine feste Länge der Strings angeben? Dann ist mein Ansatz korrekt?

Namenloser 25. Dez 2009 18:40

Re: Indy 10 - Protokoll richtig aufbauen
 
Zitat:

Zitat von Dragon27
Sprich ich muss eine feste Länge der Strings angeben? Dann ist mein Ansatz korrekt?

Ja, allerdings kann man soweit ich weiß nur längen bis 255 vorgeben. Ob das reicht, hängt vom Anwendungszweck ab. Eleganter wäre es aber, das ganze mit Streams zu lösen - das geht dann in etwa so (wie man die Streams mit Indy versendet, weiß ich gerade leider nicht mehr):
Delphi-Quellcode:
type
  TProtokoll=record
    Befehl:String;
    Ter1:String;
    Ter2:String;
    Ter3:String;
    Ter4:String;
    BDaten:Boolean;
  end;

procedure WriteRecordToStream(Rec: TProtokoll; Stream: TStream);
var
  StrLength: integer;
begin
  StrLength := length(Rec.Befehl);
  Stream.Write(StrLength, SizeOf(StrLength));
  Stream.Write(Rec.Befehl[1], StrLength);

  StrLength := length(Rec.Ter1);
  Stream.Write(StrLength, SizeOf(Ter1));
  Stream.Write(Rec.Ter1[1], StrLength);

  StrLength := length(Rec.Ter2);
  Stream.Write(StrLength, SizeOf(StrLength));
  Stream.Write(Rec.Ter2[1], StrLength);

  ...

  Stream.Write(Rec.BDaten, SizeOf(Rec.BDaten));

end;

procedure ReadRecordFromStream(Rec: TProtokoll; Stream: TStream);
var
  StrLength: integer;
begin
  Stream.Read(StrLength, SizeOf(StrLength));
  SetLength(Rec.Befehl, StrLength);
  Stream.Read(Rec.Befehl[1], StrLength);

  Stream.Read(StrLength, SizeOf(StrLength));
  SetLength(Rec.Befehl, StrLength);
  Stream.Read(Rec.Ter1[1], StrLength);

  Stream.Read(StrLength, SizeOf(StrLength));
  SetLength(Rec.Befehl, StrLength);
  Stream.Read(Rec.Ter2[1], StrLength);

  ...

  Stream.Read(Rec.BDaten, SizeOf(Rec.BDaten));
end;

var
  Stream: TMemoryStream;
  Rec: TProtokoll;
begin
  Stream := TMemoryStream.Create;
  Rec.BDaten := False;
  Rec.Befehl := 'Foo';
  Rec.Ter1 := 'Bar';
  Rec.Ter2 := '42';
  ...
  // Record im Stream speichern
  WriteRecordToStream(Rec, Stream);

  // Record aus Stream laden:
  Stream.Position := 0;
  ReadRecordFromStream(Rec, Stream);
  ...
end;
Noch besser wäre es, TProtokoll als Klasse anzulegen und dann zwei Methoden LoadFromStream und SaveToStream anzulegen.

Dragon27 25. Dez 2009 18:50

Re: Indy 10 - Protokoll richtig aufbauen
 
Hallo,

danke für deine Mühe!

Sehe ich das richtig, dass wenn ich Streams verwende auch kein Problem beim Dateiversand besteht?

Danke!

DataCool 25. Dez 2009 19:09

Re: Indy 10 - Protokoll richtig aufbauen
 
@Dragon27:

Mit Streams bist Du komplett offen(auch was Dateiversand angeht).
beim versenden eines Streams wird vor dem Stream die Größe des Streams verschickt und danach x Bytes.
Der Server liesst die GRößenangabe und weiß dann wieviel Bytes er lesen soll/muss.
Ich würde dann in den ersten Bytes des Streams noch eine Kennzahl unterbringen um welche Art von Stream es sich handelt, z.B.:

- 1. Textnachricht
- 2. Textinfo
- ....
- 200 Datei-/Filestream
etc.

^^^^ nur ein Bsp.

Greetz Data

Dragon27 25. Dez 2009 19:18

Re: Indy 10 - Protokoll richtig aufbauen
 
Danke für den Hinweis...

Gibt es dazu Beispiele? Ich verstehe nicht ganz wie ich das umsetzen kann/soll.
Sprich ich erstelle eine Klasse die ich in einen Stream lade. Aber wie mache
ich das mit 1 2 200 ?

Danke!

Bernhard Geyer 25. Dez 2009 19:19

Re: Indy 10 - Protokoll richtig aufbauen
 
Zitat:

Zitat von Dragon27
Ich würde das ganze gerne relativ offen lassen um auch Dateien schicken zu können.... Ist mein Ansatz gut? Habt Ihr einen besseren?

Relativ aber nicht wirklich offen. Was ist wenn du einen Befehl mit 5 Parametern benötigst?
Schau dir mal ASN.1 oder XML als Codierungsformat für deine Befehle an. Dann bist du viel flexibler. Sinnvoll ist auch eine Versionsangabe des Protokolls zu integrieren oder eine Capability-Abfrage der Gegenstelle.

REST und JSON wären auch noch was du dir mal anschauen könntest.

DataCool 25. Dez 2009 19:57

Re: Indy 10 - Protokoll richtig aufbauen
 
@Bernhard:

Es ging darum mit dem ersten Byte die Art des Streams zu unterscheiden,
je nach "Streamart" können x-beliebig viele Informationen im Stream stehen,
der Stream kann auch XML sein.

Natürlich kann mann auch immer von einer XML Struktur ausgehen,
meistens reicht aber die oben genannte Mthode aus.

Greetz Data


Alle Zeitangaben in WEZ +1. Es ist jetzt 03:23 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