Entwickler-Ecke

Open Source Projekte - TNBFPA v1.12 - SocketKompos mit Protokollfunktionen


Narses - Do 22.03.07 02:09
Titel: TNBFPA v1.12 - SocketKompos mit Protokollfunktionen
Socket-Komponenten mit integriertem Protokoll-Adapter

Wer das Binär-Protokoll-Tutorial [http://www.delphi-library.de/topic_66706.html] kennt, wird den verwendeten TProtocolAdapter bestimmt wiedererkennen (der allerdings hier bereits in einer weiterentwickelten Form vorliegt). Kenntnis des Tutorials wäre sicher sehr hilfreich bei der Verwendung der hier vorgestellten Komponenten, ist aber nicht zwingend notwendig.
Die Komponenten werden in die Palette der IDE installiert, können aber auch dynamisch verwendet werden. Im Projekt-Archiv ist eine ausführliche Anleitung zur Installation der Komponenten enthalten. Es ist übrigens nicht notwendig, die Socket-Komponenten [http://www.delphi-library.de/topic_64438.html] (TClientSocket und TServerSocket) in der IDE installiert zu haben (somit stellen diese beiden Komponenten eine Möglichkeit dar, auch in PE-Delphi-Versionen wieder IDE-Integration für Sockets-basierte Komponenten zu bekommen).

Fortgeschrittene mit Kenntnis des oben erwähnten Binär-Protokoll-Tutorials werden sich sicherlich darüber freuen, die Anbindung an die Sockets nicht mehr "von Hand" machen zu müssen. Aber auch Anfänger in Sachen Netzwerk könn(t)en mit den vorgestellten Komponenten eine einfache Lösung für klassische Probleme bei der Kommunikation finden (Daten-Typen/-Pakete auseinanderhalten, Ereignisse korrekt handhaben [http://www.delphi-library.de/topic_56194.html]), ohne den kompletten Hintergrund in allen Details kennen und beherrschen zu müssen.

Das Projekt-Archiv im Anhang dieses Beitrags enthält:
Die nächsten netzwerkprogrammierungsbezogenen Tutorials von mir werden auf diesen Komponenten aufbauen, da hiermit die Netzwerkkommunikation über ein (proprietäres) Protokoll "kinderleicht" ist. ;)

History:

Änderungen in TNBFPA v1.20, Doku v1.06 vom 24.02.2010:
Änderungen in TNBFPA v1.12, Doku v1.06 vom 27.08.2008:
Änderungen in TNBFPA v1.11, Doku v1.06 vom 21.08.2007:
Komplette Version-History im Quelltext.

cu
Narses


Bullweih - Do 29.03.07 13:33
Titel: Fehler in Delphi 6
Moin Moin

Habe Deine Komponente gezogen und mit Delphi 6 getestet.
Bekomme beim Compilieren den Fehler das er
FConnectionsRef.NameValueSeparator nicht kennt.
Ich gehe mal davon aus das es sich auch um FConnectionsRef.Delimiter handelt oder zumindestens ersetzt werden kann.

MfG
Bulli


Narses - Do 29.03.07 23:07

Moin!

user profile iconBullweih hat folgendes geschrieben:
mit Delphi 6 getestet.
Bekomme beim Compilieren den Fehler das er
FConnectionsRef.NameValueSeparator nicht kennt.
Ich gehe mal davon aus das es sich auch um FConnectionsRef.Delimiter handelt oder zumindestens ersetzt werden kann.

Nein, damit ist das Standard-Trennzeichen für den Zugriff über TStrings.Values[] gemeint (hat das D6 etwa noch nicht... :gruebel: muss mal am anderen Rechner forschen gehen... :oops:). Im Zweifel einfach FConnectionsRef.NameValueSeparator durch ein '=' ersetzen (tritt 2x auf: Zeile #1667 und #2432).

Ich lass mir mal was dazu einfallen... :?

cu
Narses


chrisdrury - Fr 30.03.07 07:30

Ist vielleicht auch an eine Version für Delphi 5 gedacht?
:wink:


Bullweih - Fr 30.03.07 08:30
Titel: Jo Danke ...
für die schnelle Antwort.
Die Komponente funzt einwandfrei. Hatte noch keine Probleme damit auch mit sehr großen Datenmengen.
Was vorher leider nicht ging oder nur mit sehr großem Aufwand zu bewerkstelligen war.

Feine Sache das ...

MfG
Bullweih


Narses - Fr 30.03.07 11:05

Moin!

user profile iconchrisdrury hat folgendes geschrieben:
Ist vielleicht auch an eine Version für Delphi 5 gedacht? :wink:

Ich hab kein D5... :? Hast du´s schon probiert? Wir können ja mal sehen, ob wir´s da auch zum Laufen kriegen. ;)



user profile iconBullweih hat folgendes geschrieben:
Jo Danke ... für die schnelle Antwort.

Bitte, war ja nur ein kleiner Eingriff für D6. ;)

user profile iconBullweih hat folgendes geschrieben:
Die Komponente funzt einwandfrei. Hatte noch keine Probleme damit auch mit sehr großen Datenmengen.
Was vorher leider nicht ging oder nur mit sehr großem Aufwand zu bewerkstelligen war.

Feine Sache das ...

Danke für das Lob! :D

cu
Narses


BenBE - So 01.04.07 22:32

user profile iconNarses hat folgendes geschrieben:
Moin!

user profile iconchrisdrury hat folgendes geschrieben:
Ist vielleicht auch an eine Version für Delphi 5 gedacht? :wink:

Ich hab kein D5... :? Hast du´s schon probiert? Wir können ja mal sehen, ob wir´s da auch zum Laufen kriegen. ;)

Wenn der besagte Fehler unter D6 gefixt ist, sollte die Komponente auch problemlos auf D5 laufen. Hab auch zum Testen D4 da. Falls also die Kompatibilität soweit getrieben werden sollte ;-)
@Narses: NameValueSeparator gibt's unter D5 UND D6 nicht.

user profile iconNarses hat folgendes geschrieben:
user profile iconBullweih hat folgendes geschrieben:
Jo Danke ... für die schnelle Antwort.

Bitte, war ja nur ein kleiner Eingriff für D6. ;)

D.h. müsste jetzt auch mit D5 laufen.

user profile iconNarses hat folgendes geschrieben:
user profile iconBullweih hat folgendes geschrieben:
Die Komponente funzt einwandfrei. Hatte noch keine Probleme damit auch mit sehr großen Datenmengen.
Was vorher leider nicht ging oder nur mit sehr großem Aufwand zu bewerkstelligen war.

Feine Sache das ...

Danke für das Lob! :D

cu
Narses

Naja ... Werd wahrscheinlich demnächst auch ein kleines Protokoll darauf aufsetzen ... (Naja ... Mischung aus RFC2440 und dem Proto der Kompo ;-)


chrisdrury - Mo 02.04.07 08:11

user profile iconNarses hat folgendes geschrieben:
Moin!

user profile iconchrisdrury hat folgendes geschrieben:
Ist vielleicht auch an eine Version für Delphi 5 gedacht? :wink:

Ich hab kein D5... :? Hast du´s schon probiert? Wir können ja mal sehen, ob wir´s da auch zum Laufen kriegen. ;)


Hallo Narses,
ich habe jetzt mal versucht, Deine Komponente unter D5 zu installieren.
Erste Fehlermeldung: siehe fehler.jpg im Anhang
Bei ftKeepAlive = 0 nur ftKeepAlive gesetzt, weiter geht's:

Zweite Fehlermeldung: siehe fehler1.jpg
PCardinal in Cardinal geändert, weiter:

Dritte Fehlermeldung: siehe fehler2.jpg
Undefinierter Bezeichner: GUIDToString, ComObj in uses eingefügt, weiter:

vierte Fehlermeldung: siehe fehler3.jpg
Zeigertyp erwartet, wat nu?:gruebel:


chrisdrury - Mo 02.04.07 08:12

Anbei noch der vierte Fehler: :wink:


BenBE - Mo 02.04.07 08:34

PCardinal ist, wie der Name sagt, ein Zeiger auf einen Cardinal ...

Also:

Delphi-Quelltext
1:
type PCardinal = ^Cardinal;                    

einfügen am Anfang der Unit und deine eine Ersetzung rückgängig machen.


Born-to-Frag - Mo 02.04.07 09:48

Moin!

Hast du wieder super gemacht, Narses :zustimm:
Werde es bei Gelegenheit mal ausführlich testen, hab im Moment leider nicht so viel Zeit (auch kaum aktiv hier :()


greetz


//Bin schon bissl am testen, und was mir natürlich gleich auffällt: Ich habe einen Client connecten lassen mit deinem altem BFPA -> Exception :shock:
Macht mir nix aus, nur eine Anmerkung ;)


Narses - Mo 02.04.07 10:34

Moin!

user profile iconchrisdrury hat folgendes geschrieben:
Bei ftKeepAlive = 0 nur ftKeepAlive gesetzt

Jo, ist klar, vermerkt. ;)

user profile iconchrisdrury hat folgendes geschrieben:
PCardinal in Cardinal geändert

Argh! :shock: Hat D5 etwa keinen PCardinal im Angebot... Auf jeden Fall nicht durch Cardinal ersetzen, ist ja ein Zeigertyp (siehe user profile iconBenBEs Beitrag)!

Ich werd mich drum kümmern.

user profile iconchrisdrury hat folgendes geschrieben:
Undefinierter Bezeichner: GUIDToString, ComObj in uses eingefügt

OK, vermerkt. ;)

user profile iconchrisdrury hat folgendes geschrieben:
Zeigertyp erwartet

Folgefehler, s.o., ist damit erledigt. ;)



user profile iconBorn-to-Frag hat folgendes geschrieben:
Hast du wieder super gemacht, Narses :zustimm:

Danke, scheint aber noch etwas zu kinderkränkeln... :? ;)

user profile iconBorn-to-Frag hat folgendes geschrieben:
Bin schon bissl am testen, und was mir natürlich gleich auffällt: Ich habe einen Client connecten lassen mit deinem altem BFPA -> Exception :shock:

Uff, hatte ich auch probiert (klar, eigentlich ;) aber ohne Exception)... Details... wo genau... :?:

cu
Narses


chrisdrury - Mo 02.04.07 10:34

Danke @ BenBE!
Jetzt läuft's auch unter Delphi 5!! 8) :P :dance2:


Born-to-Frag - Mo 02.04.07 14:28

user profile iconNarses hat folgendes geschrieben:
user profile iconBorn-to-Frag hat folgendes geschrieben:
Bin schon bissl am testen, und was mir natürlich gleich auffällt: Ich habe einen Client connecten lassen mit deinem altem BFPA -> Exception :shock:

Uff, hatte ich auch probiert (klar, eigentlich ;) aber ohne Exception)... Details... wo genau... :?:


Hi,

war mein Fehler, funktioniert super! :autsch:
// es liegt daran, dass ich keinen client connecten lassen kann der das BFPA mit extra Socket Komponenten benutzt (zu alt schon? :D) Wenn du willst guck ich trotzdem nochmal genau wo der Fehler lag..

greetz


Narses - Mo 02.04.07 15:28

Moin!

user profile iconBorn-to-Frag hat folgendes geschrieben:
war mein Fehler, funktioniert super! :autsch:

Schwitz... 8) OK, Danke für den Test. ;)

user profile iconBorn-to-Frag hat folgendes geschrieben:
es liegt daran, dass ich keinen client connecten lassen kann der das BFPA mit extra Socket Komponenten benutzt (zu alt schon? :D)

Ja, das steht aber auch in der Doku... :zwinker: rtfm... (duck weg) :P

Transportprotokoll-Header-Versionen:
BinProtoTut: 'NBFP10'
Kompo-Version: 'NBFP20'
:idea:

user profile iconBorn-to-Frag hat folgendes geschrieben:
Wenn du willst guck ich trotzdem nochmal genau wo der Fehler lag.

Wenn du Zeit hast; würde mich schon interessieren (ggfs. -> PN, scheint ja was spezifisches zu sein).

cu
Narses


hui1991 - Di 03.04.07 12:22

Hi,

diese Komponente funktioniert auf meinem Delphi 7 eigentlich garnicht.
Der Fehler ist ich installiere es wie normal.
Schaue im Internet Register ob es da ist.
Sehe es ist da.
Danach schließe ich es.
Öffne eine neue Form und aufeinmal fehlt die Komponente.
Was soll ich tun das sie dauert da bleibt?
Neue installieren geht auch nicht.
Und ich weis net wo ich des Deinstallieren soll.

mfg
hui1991


Narses - Di 03.04.07 12:30

Moin!


user profile iconhui1991 hat folgendes geschrieben:
Was soll ich tun das sie dauert da bleibt?
Neue installieren geht auch nicht.
Und ich weis net wo ich des Deinstallieren soll.

Das sieht mir doch stark danach aus, dass sie bereits installiert ist, aber evtl. in einem anderen Registerbereich? :gruebel:

Du bist nach Anleitung in Kapitel 2 vorgegangen und hast auch eine Meldung der Art: "Als Ergebnis des Neucompilierens des installierten Packages..." bekommen?

cu
Narses


hui1991 - Di 03.04.07 12:48

Nein das kam nicht:
"Als Ergebnis des Neucompilierens des installierten Packages..."

Hätte mir ja jemand sagen können das der Download unvollständig war.
Die PDF war bei mir garnet dabei.
Ich habe es etz runter geladen.
Und habe die PDF geöffnet.
Ich habe es nicht so gemacht.
Ich habe ein neues Package gemacht und die dort eingefügt und dann auf Installieren gedrückt.
Dann war sie da.
Nach delphi neustart war sie dann wieder weg.
Keine Ahnung warum das aufeinmal net geht.

Ich habe etz es so wie in der Anleitung gemacht und dann kam das hier:
"Als Ergebnis des Neucompilierens des installierten Packages..."
Blos in englisch ^^

Naja dann habe ich auf JA gedrückt und dann kam die Meldung das erfolgreich installiert ist
Ich habe es geschlossen und dann neue Application ausgewählt und siehe da es ist drin.

Naja Danke für deine Antwort hat mir eigentlich geholfen ^^
Ich teste es dann mal Später ^^

MfG
hui1991


Narses - Mi 04.04.07 12:12

Moin!

Neue Version TNBFPA v1.03, Doku v1.01, Details siehe oben im 1. Beitrag.

Da ich kein D5 habe, wäre ich über einen Hinweis dankbar, ob es jetzt so "durchläuft". ;)

cu
Narses


BenBE - Fr 06.04.07 15:08

Wünschenswerte Funktion für neue Releases:

- Protokoll-ID und Version über OI einstellbar (Sonst wären ja theoretisch alle Anwendungen miteinander kompatibel ;-))

- OnEncryptData \ OnDecryptData pro Datenblock (feste größe einstellbar \ an Framegrenzen) decodierbar (um z.B. teilweise verschlüsselte Kommunikation zu realisieren)

- Einstellbare adaptive Framegrößen-Übertragung (um ähnlich RFC2440 die für die Größenangabe benötigten Informationen zu reduzieren)

//Edit: Feature-Wunschliste ergänzt


Narses - Sa 07.04.07 00:33

Moin!

user profile iconBenBE hat folgendes geschrieben:
Protokoll-ID und Version über OI einstellbar (Sonst wären ja theoretisch alle Anwendungen miteinander kompatibel ;-))

Du hast den Transportprotokoll-Header in den "falschen Hals" gekriegt, user profile iconBenBE. ;) Es geht nämlich genau darum: die Komponente soll mit anderen Kompos, egal wo kompiliert, "reden" können. Es ist also ein Komponenten-Standard, der da etabliert werden soll. :mahn: Was du möchtest, muss erst im Anwendungsprotokoll definiert und behandelt werden: Anwendungsidentifikation und Versionierung! :idea:

user profile iconBenBE hat folgendes geschrieben:
OnEncryptData \ OnDecryptData pro Datenblock (feste größe einstellbar \ an Framegrenzen) decodierbar (um z.B. teilweise verschlüsselte Kommunikation zu realisieren)

Ja, da hatte ich auch schon drüber nachgedacht... ;) aber den Gedanken wieder verworfen, weil mir das so schnell so komplex wurde (das interne Caching ist da nicht ganz unproblematisch), dass ich mir nicht mehr sicher war, ob ich die Kompo noch 2007 veröffentlicht kriege... 8) Fazit: mal sehen, vielleicht mal, wenn ich vieeel Zeit und Langeweile habe... :zwinker: Ansatz: definiere für verschlüsselte Frames entsprechende Token, dann geht das auch so. :D

user profile iconBenBE hat folgendes geschrieben:
Einstellbare adaptive Framegrößen-Übertragung (um ähnlich RFC2440 die für die Größenangabe benötigten Informationen zu reduzieren)

Hehe, du gibst aber auch nicht auf :mrgreen: wenn du das unbedingt haben willst, dann mach dir mal Gedanken, wie dann das Transportprotokoll dafür aussehen soll und schick mir eine PN mit dem Vorschlag... (das ist nicht soo einfach, wie du dir das Vorstellst) :P Abgesehen davon: was willst du denn da aktuell einsparen? 1 Byte, wenn die Datenmenge < 255 Zeichen im Frame ist? Was soll das bringen? :gruebel: ;)

cu
Narses


Narses - Do 12.04.07 23:25

Moin!

Ein weiteres (Demo-)Projekt mit den TNBFPA-Komponenten: Mal-FileTransfer-Chat [http://www.delphi-library.de/viewtopic.php?p=433259#433259] ;)

cu
Narses


Narses - Mo 07.05.07 23:03

Moin!

Hier das nächste Tutorial aus meiner Netzwerk-Reihe: Multiplayer-TicTacToe [http://www.delphi-forum.de/topic_72573.html] ;)

Viel Erfolg damit,

cu
Narses


Narses - So 03.06.07 19:27

Moin!

Neue Version (v1.04, Bugfixes und neue Funktionen), Details im ersten Beitrag. ;)

cu
Narses


Narses - Mo 04.06.07 15:20

Moin!

Neue Version 1.05 (FIX in der Ereignisreihenfolge des TNBFPAServer), Details im ersten Beitrag. ;)

cu
Narses


Narses - Sa 23.06.07 21:27

Moin!

Neue Komponenten- (v1.06) und Doku-Versionen (v1.04), Details - wie immer - im ersten Beitrag. ;)

//EDIT: Update der Komponente auf v1.07 (Bugfix)

cu
Narses


Sko - Do 05.07.07 11:21

Hallo Narses,

ich habe mit deinen Komponenten einen Chat gebastelt und wollte nun die Verschlüsselungsereignisse benutzen. Dazu habe ich eine RCx-Unit von negaH benutzt. Das ganze sieht jetzt auf beiden Seiten(Client und Server) so aus:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
procedure TMainForm.ClientEncryptData(Sender: TObject; PA: TProtocolAdapter;
  var Buffer; const Size: Integer);
var
  ARCx: TRCxContext;
begin
  RCxInit(ARCx,'<Passwort>');
  RCxEncode(ARCx,Buffer,Buffer,Size);
  RCxDone(ARCx);
end;

procedure TMainForm.ClientDecryptData(Sender: TObject; PA: TProtocolAdapter;
  var Buffer; const Size: Integer);
var
  ARCx: TRCxContext;
begin
  RCxInit(ARCx,'<Passwort>');
  RCxDecode(ARCx,Buffer,Buffer,Size);
  RCxDone(ARCx);
end;
Allerdings kommen manchmal 2 gesendete Pakete als ein Paket beim Empfänger an, wodurch die Entschlüsselung nicht funktioniert.

Beispiel:
Server sendet 1B4BA8037D0EF2119A8E9FE15BF94E2B3EEBB6EA und 53E3DD9B62D668F41801ED0B8C336B98AECB77542B0D0720D8358D96D14C
Client empfängt 1B4BA8037D0EF2119A8E9FE15BF94E2B3EEBB6EA53E3DD9B62D668F41801ED0B8C336B98AECB77542B0D0720D8358D96D14C


BenBE - Do 05.07.07 11:52

Das ist kein Fehler der Komponente, sondern eine bewusste Eigenart der TCP API. Um die Trennung der Pakete musst Du dich ggf. selber probieren.

Einzige Möglichkeit hier ist, einen Block-Chiffre zu nutzen, der Positionsuabhängig\Block-Unabhängig ist.

Edit: Bzw. dafür sorgen, dass Du nach jedem Paket den Status des Chiffre speicherst und mit diesem beim nächsten Paket fortsetzt. Damit hast Du dann nämlich den Fall, dass du einen langen Datenstrom hast und Sender\Empfänger synchron laufen.


Narses - Do 05.07.07 12:00

Moin!

(Auf die Frage hab´ ich schon gewartet... ;))

user profile iconSko hat folgendes geschrieben:
ich habe mit deinen Komponenten einen Chat gebastelt und wollte nun die Verschlüsselungsereignisse benutzen. Dazu habe ich eine RCx-Unit von negaH benutzt.

Du verwendest also eine kontextabhängige Verschlüsselung; dabei ist wichtig zu wissen, dass diese Verschlüsselungen bei Streams positionsabhängig sind, also immer einen kompletten Stream mit einem Kontext verschlüsseln müssen, sonst klappt´s nicht! :mahn: ;)

Es gibt 2 grundsätzlich verschiedene Ansätze, wie man mit den TNBFPAs Verschlüsselung betreiben kann:

(1) Ohne die Encryption-Ereignisse: die Nutzdaten bereits verschlüsselt an Kommandosequenzen anfügen, dabei wird dann das Transportprotokoll im Klartext übertragen und die Daten sind separat verschlüsselt

(2) Mit den Encryption-Ereignissen: hier wird die gesamte Sitzung als Stream betrachtet, der dann auch (im Kontext) verschlüsselt werden muss, es wird damit also auch das Transportprotokoll verschlüsselt

Du hast nun die Variante 1,5 verwendet ;) weil du in den Ereignissen immer wieder einen neuen Kontext generierst. :idea: Und das klappt dann nicht, weil damit die Entschlüsselung nicht mehr klar kommt (durch das interne Caching der Komponente). :mahn:

Deshalb: entweder (1) verwenden und nur die Nutzdaten verschlüsseln (das kannst du dann wie schon von dir vorgestellt mit jeweils separatem Kontext machen) oder (2) korrekt verwenden. ;) Nämlich:
im Server:
- beim OnCreatePA den Kontext erstellen
- in den Ereignissen verwenden
- beim OnDestroyPA den Kontext freigeben
im Client:
- im OnReset den Kontext anlegen
- in den Ereignissen verwenden
- im OnDisconnect den Kontext freigeben

Fazit: für kontextabhängige Verschlüsselungen muss der Konktext auch für die gesamte Sitzungsdauer beibehalten werden. :mahn: ;)

cu
Narses


Sko - Do 05.07.07 12:10

Danke für eure Antworten :zustimm:

Also brauche ich für jeden Client einen eigenen TRCxContext ? Dann werd ich den an den ProtokollAdapter mit dran hängen, oder hab ich was falsch verstanden?


Narses - Do 05.07.07 12:25

Moin!

user profile iconSko hat folgendes geschrieben:
Also brauche ich für jeden Client einen eigenen TRCxContext ? Dann werd ich den an den ProtokollAdapter mit dran hängen, oder hab ich was falsch verstanden?

Yip, genau so hab´ ich mir das gedacht. ;)

cu
Narses


Sko - Do 05.07.07 14:07

Hmm, das wollte auch nicht so richtig, darum hab ich mich jetzt für Variante 1 entschieden, das geht ganz gut, danke für deine Hilfe.


BenBE - Do 05.07.07 14:10

@NArses: Kannst Du für die Variante 2 mal ein ganz kleines Demo schreiben???

Wünschenswert dabei wäre mit Beispiel, wie man während der Verbindung die Verschlüsslung an- und ausschalten kann (d.h. über einen Protokoll-Befehl dynamisch festlegen kann, was verschlüsselt wird und was nicht ...


Narses - Do 05.07.07 14:55

Moin!

user profile iconSko hat folgendes geschrieben:
Hmm, das wollte auch nicht so richtig,

Hm, OK, ist auch nicht soo ganz einfach, geb ich zu. :?

user profile iconSko hat folgendes geschrieben:
darum hab ich mich jetzt für Variante 1 entschieden, das geht ganz gut, danke für deine Hilfe.

Fein, viel Erfolg noch. :zustimm:


user profile iconBenBE hat folgendes geschrieben:
Kannst Du für die Variante 2 mal ein ganz kleines Demo schreiben?

Ja, ich merk´ schon, das wird wohl nötig sein. :? Ich mach mal eins. ;)

user profile iconBenBE hat folgendes geschrieben:
Wünschenswert dabei wäre mit Beispiel, wie man während der Verbindung die Verschlüsslung an- und ausschalten kann (d.h. über einen Protokoll-Befehl dynamisch festlegen kann, was verschlüsselt wird und was nicht ...

Das geht nicht :arrow: Variante (1) nehmen. Wenn (2), dann über die gesamte Verbindung. :mahn:

cu
Narses


Sko - Do 05.07.07 21:55

user profile iconNarses hat folgendes geschrieben:
user profile iconBenBE hat folgendes geschrieben:

Kannst Du für die Variante 2 mal ein ganz kleines Demo schreiben?


Ja, ich merk´ schon, das wird wohl nötig sein. :? Ich mach mal eins. ;)

Ja, das wäre super :D


Narses - Fr 06.07.07 02:04

Moin!

:oops: Leider war im TProtocolAdapter noch ein sehr fieser kleiner Bug, der allerdings nur bei Verschlüsselung und mehr als einer Verbindung zum Tragen kam... :twisted: (da ich bisher die Verschlüsselung als "nice-to-have-feature" nicht wirklich verwendet habe und in meinem Testprojekt immer nur eine Verbindung verwendet wird, ist mir das bisher leider nicht aufgefallen :|). Togal, neue Version v1.08 der Komponente im ersten Beitrag zum Download; bei der Gelegenheit auch gleich noch was zu Verschlüsselung in die Doku (v1.05) eingepflegt. ;)


Jetzt zum versprochenen Beispiel für verschlüsselte Kommunikation (das komplette Projekt ist auch im Download-Archiv enthalten, s. erster Beitrag). Dazu werden wir diese kleine kontextsensitive Doof-Verschlüsselung verwenden, um jetzt nicht auch noch mit einem "komplizierten" Verfahren zu kämpfen: :zwinker:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
type
  TDemoCipher = class(TObject)
  private
    FEncryptionKey: Byte;
    FDecryptionKey: Byte;
    procedure DoEncryption(var Buffer; const Size: Integer; var Key: Byte);
  public
    procedure Reset;
    procedure Encrypt(var Buffer; const Size: Integer);
    procedure Decrypt(var Buffer; const Size: Integer);
  end;

implementation

procedure TDemoCipher.Reset;
begin
  FEncryptionKey := 0;
  FDecryptionKey := 0;
end;

procedure TDemoCipher.DoEncryption(var Buffer; const Size: Integer; var Key: Byte);
  var
    i: Integer;
begin
  for i := 0 to Size-1 do begin
    TByteArray(Buffer)[i] := TByteArray(Buffer)[i] xor Key;
    Inc(Key);
  end;
end;

procedure TDemoCipher.Encrypt(var Buffer; const Size: Integer);
begin
  DoEncryption(Buffer,Size,FEncryptionKey);
end;

procedure TDemoCipher.Decrypt(var Buffer; const Size: Integer);
begin
  DoEncryption(Buffer,Size,FDecryptionKey);
end;

Folgender Code ist im Server des Chat-Demos, das als Basis dient, zu ergänzen:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
// neue Verbindung hergestellt
procedure TServerMain.NBFPAServer1CreatePA(Sender: TObject; PA: TProtocolAdapter);
begin
  PA.RefObject := TDemoCipher.Create; // Verschlüsselungskontext anlegen
  PA.OwnsRefObject := TRUE; // beim Freigeben den Kontext mit entsorgen
end;

// Sendedaten im Kontext der Verbindung verschlüsseln
procedure TServerMain.NBFPAServer1EncryptData(Sender: TObject;
  PA: TProtocolAdapter; var Buffer; const Size: Integer);
begin
  TDemoCipher(PA.RefObject).Encrypt(Buffer,Size);
end;

// Empfangsdaten im Kontext der Verbindung entschlüsseln
procedure TServerMain.NBFPAServer1DecryptData(Sender: TObject;
  PA: TProtocolAdapter; var Buffer; const Size: Integer);
begin
  TDemoCipher(PA.RefObject).Decrypt(Buffer,Size);
end;

Und hier die Änderungen/Ergänzungen im Client-Code:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
// Bei Programmstart ausführen
procedure TClientMain.FormCreate(Sender: TObject);
begin
  FDemoCipher := TDemoCipher.Create; // statischen Verschlüsselungskontext anlegen
  NBFPAClient1ConnectionStateChange(Self); // GUI aktualisieren
end;

// Verbindung zu einem Server (erneut) hergestellt
procedure TClientMain.NBFPAClient1Reset(Sender: TObject; PA: TProtocolAdapter);
begin
  FDemoCipher.Reset; // Kontext (re-)initialisieren
end;

// Sendedaten im statischen Kontext verschlüsseln
procedure TClientMain.NBFPAClient1EncryptData(Sender: TObject;
  PA: TProtocolAdapter; var Buffer; const Size: Integer);
begin
  FDemoCipher.Encrypt(Buffer,Size);
end;

// Empfangsdaten im statischen Kontext entschlüsseln
procedure TClientMain.NBFPAClient1DecryptData(Sender: TObject;
  PA: TProtocolAdapter; var Buffer; const Size: Integer);
begin
  FDemoCipher.Decrypt(Buffer,Size);
end;

// Bei Programmende ausführen
procedure TClientMain.FormDestroy(Sender: TObject);
begin
  FDemoCipher.Free; // Kontext-Objekt freigeben
  // Wenn der Kontext aus Sicherheitsgründen schon vorher entsorgt werden soll,
  // einfach im OnDisconnect leeren bzw. reinitialisieren.
end;

Mit diesen Ergänzungen läuft die Kommunikation jetzt verschlüsselt ab.

cu
Narses


Narses - Mo 09.07.07 19:45

Moin!

Tja :| das Thema Verschlüsselung hätte wohl noch etwas intensivere Aufarbeitung vertragen können... :oops: Leider war noch ein Bug diesbezüglich drin :arrow: neue Version v1.09 der Komponente im ersten Beitrag. ;)


Aber als "Entschädigung" :zwinker: hier noch ein Vorschlag, wie man eine vollduplex-symmetrische RC4-Verschlüsselung integrieren könnte. Zunächst die RC4-Adapter-Klasse, um eine RC4-Unit an den Protokoll-Adapter anzuknoten (die Aufrufe der RC4-Unit sind ggfs. entsprechend anzupassen, je nach Unit eben):

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
uses
  ..., RC4;

type
  TRC4Adapter = class(TObject)
  private
    FEncryptionContext: TRC4Context;
    FDecryptionContext: TRC4Context;
  public
    constructor Create(const AKey: String);
    destructor Destroy; override;
    procedure Reset(const AKey: String);
    procedure Encrypt(var Buffer; const Size: Integer);
    procedure Decrypt(var Buffer; const Size: Integer);
  end;

implementation

constructor TRC4Adapter.Create(const AKey: String);
begin
  inherited Create;
  Reset(AKey);
end;

destructor TRC4Adapter.Destroy;
begin
  RC4Done(FEncryptionContext);
  RC4Done(FDecryptionContext);
  inherited;
end;

procedure TRC4Adapter.Reset(const AKey: String);
begin
  RC4Init(FEncryptionContext,AKey);
  RC4Init(FDecryptionContext,AKey);
end;

procedure TRC4Adapter.Encrypt(var Buffer; const Size: Integer);
begin
  RC4Code(FEncryptionContext,Buffer,Buffer,Size);
end;

procedure TRC4Adapter.Decrypt(var Buffer; const Size: Integer);
begin
  RC4Code(FDecryptionContext,Buffer,Buffer,Size);
end;

Die Einbindung ins Demo-Server-Projekt:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
// neue Verbindung hergestellt
procedure TServerMain.NBFPAServer1CreatePA(Sender: TObject; PA: TProtocolAdapter);
begin
  PA.RefObject := TRC4Adapter.Create('*geheim*'); // Verschlüsselungskontext anlegen
  PA.OwnsRefObject := TRUE; // beim Freigeben den Kontext mit entsorgen
end;

// Sendedaten im Kontext der Verbindung verschlüsseln
procedure TServerMain.NBFPAServer1EncryptData(Sender: TObject;
  PA: TProtocolAdapter; var Buffer; const Size: Integer);
begin
  TRC4Adapter(PA.RefObject).Encrypt(Buffer,Size);
end;

// Empfangsdaten im Kontext der Verbindung entschlüsseln
procedure TServerMain.NBFPAServer1DecryptData(Sender: TObject;
  PA: TProtocolAdapter; var Buffer; const Size: Integer);
begin
  TRC4Adapter(PA.RefObject).Decrypt(Buffer,Size);
end;

Und hier noch der Client:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
// Bei Programmstart ausführen
procedure TClientMain.FormCreate(Sender: TObject);
begin
  FRC4Adapter := TRC4Adapter.Create(''); // nur Objekt anlegen
  NBFPAClient1ConnectionStateChange(Self); // GUI aktualisieren
end;

// Verbindung zu einem Server (erneut) hergestellt
procedure TClientMain.NBFPAClient1Reset(Sender: TObject; PA: TProtocolAdapter);
begin
  FRC4Adapter.Reset('*geheim*'); // Kontext (re-)initialisieren
end;

// Sendedaten im statischen Kontext verschlüsseln
procedure TClientMain.NBFPAClient1EncryptData(Sender: TObject;
  PA: TProtocolAdapter; var Buffer; const Size: Integer);
begin
  FRC4Adapter.Encrypt(Buffer,Size);
end;

// Empfangsdaten im statischen Kontext entschlüsseln
procedure TClientMain.NBFPAClient1DecryptData(Sender: TObject;
  PA: TProtocolAdapter; var Buffer; const Size: Integer);
begin
  FRC4Adapter.Decrypt(Buffer,Size);
end;

// Bei Programmende ausführen
procedure TClientMain.FormDestroy(Sender: TObject);
begin
  FRC4Adapter.Free; // Kontext-Objekt freigeben
  // Wenn der Kontext aus Sicherheitsgründen schon vorher entsorgt werden soll,
  // einfach im OnDisconnect leeren bzw. reinitialisieren.
end;

Viel Erfolg! :zustimm:

cu
Narses

//EDIT: hatte vergessen, den RC4-Kontext im Destruktor der Adapterklasse wieder zu leeren, ist jetzt aber mit drin. ;)


Sko - Di 10.07.07 07:34

Super, werd ich gleich mal ausprobieren, Danke :zustimm:


Narses - Di 10.07.07 10:16

Moin!

user profile iconSko hat folgendes geschrieben:
Super, werd ich gleich mal ausprobieren, Danke :zustimm:

Bitte ;) Rückmeldung erwünscht. :les: :)

cu
Narses


Sko - Di 10.07.07 21:19

Funktioniert super, keine Probleme, alles läuft wie´s soll, vielen Dank nochmal :zustimm:


Narses - Fr 13.07.07 09:33

Moin!

(Abgetrennt von hier [http://www.delphi-forum.de/viewtopic.php?p=451216#451216])

user profile iconNeotracer64 hat folgendes geschrieben:
Wie könnte ich jetzt am einfachsten mit den Kompos Datenübertragungen zwischen Server <> Client realisieren?

[...]

Es macht schon Sinn, wenn man als Server eine Datei an mehrere Clients oder nur an einen schicken möchte.
Von Client zu Server macht es schon weniger Sinn, aber ich hatte da so eine Art CVS Idee im Kopf, wo jeder seine Projekt-Dateien auch an den Server schickt, der sie dann verwaltet und mit anderen synchronisiert. Sozusagen als Sammelstelle.

[...]

Vlt. hast du eine Idee für mich, wie ich also einen Server <> Client DateiTransfer mit deinen Komponenten am besten hinbekomme?

Die Idee ist die gleiche, wie im BinProtoTut-Chat, nur dass du im Server nicht den Code verwendest, um die FileStreamChunks weiterzuleiten, sondern dort zu speichern. Ich mache mal ein konkretes Beispiel dazu, dauert aber etwas (evtl. heute Abend). ;)

cu
Narses


Narses - Sa 14.07.07 00:26

Moin!

Hier das versprochene Demo-Projekt für einen minimalen Filetransfer. Der Client verbindet sich sofort mit dem Server (Host auf "localhost" in der Komponente voreingestellt, ggfs. ändern) und kann dann auf Buttonklick und Dateiauswahlbox eine Datei an den Server senden (der Button bleibt solange deaktiviert, bis der Transfer fertig ist). Der Server speichert alle Dateien, die er von Clients erhält, im Verzeichnis der EXE ab, der Name wird aus der Anzahl der bisher gesendeten Dateien und ".txt" gebildet (ggfs. also umbenennen). Es findet keine Fehlererkennung oder sonstiges statt, das Beispiel ist wirklich sehr minimal gehalten. Im Anhang befindet sich das komplette Projekt zum selbst Ausprobieren.

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
unit UClient;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, NarsesBFPA, UProtocol;

type
  TfrmClient = class(TForm)
    OpenDialog: TOpenDialog;
    BtnSend: TButton;
    NBFPAClient: TNBFPAClient;
    procedure FormShow(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure BtnSendClick(Sender: TObject);
    procedure NBFPAClientRequestData(Sender: TObject; PA: TProtocolAdapter);
    procedure FormCreate(Sender: TObject);
  private
    FOutStream: TFileStream;
  public
    { Public-Deklarationen }
  end;

var
  frmClient: TfrmClient;

implementation

{$R *.dfm}

procedure TfrmClient.FormCreate(Sender: TObject);
begin
  FOutStream := NIL;
end;

procedure TfrmClient.FormShow(Sender: TObject);
begin
  NBFPAClient.SessionName := DateTimeToStr(Now);
  NBFPAClient.Connect;
end;

procedure TfrmClient.BtnSendClick(Sender: TObject);
begin
  if OpenDialog.Execute then begin
    BtnSend.Enabled := FALSE;
    FOutStream := TFileStream.Create(OpenDialog.FileName,
                                     fmOpenRead or fmShareDenyWrite);
    NBFPAClient.Send;
  end;
end;

procedure TfrmClient.NBFPAClientRequestData(Sender: TObject; PA: TProtocolAdapter);
  const
    CHUNK_SIZE = 2048;
  var
    Remaining: Integer;
    Cmd: TCmdSeq;
begin
  if Assigned(FOutStream) then begin
    Remaining := FOutStream.Size -FOutStream.Position;
    if (Remaining > CHUNK_SIZE) then
      Remaining := CHUNK_SIZE;
    Cmd := TCmdSeq.Create(CMD_CHUNK);
    Cmd.Add(FOutStream,Remaining);
    NBFPAClient.SendAndFree(Cmd);
    if (FOutStream.Position = FOutStream.Size) then begin
      FreeAndNil(FOutStream);
      Cmd := TCmdSeq.Create(CMD_STOP);
      NBFPAClient.SendAndFree(Cmd);
      BtnSend.Enabled := TRUE;
    end;
  end;
end;

procedure TfrmClient.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  FreeAndNil(FOutStream);
  NBFPAClient.Disconnect;
end;

end.


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
unit UServer;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, NarsesBFPA, UProtocol;

type
  TfrmServer = class(TForm)
    NBFPAServer: TNBFPAServer;
    ListBox: TListBox;
    procedure NBFPAServerConnectionsChange(Sender: TObject);
    procedure FormShow(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure NBFPAServerClientExecute(Sender: TObject;
      PA: TProtocolAdapter);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  frmServer: TfrmServer;

implementation

{$R *.dfm}

procedure TfrmServer.NBFPAServerConnectionsChange(Sender: TObject);
begin
  ListBox.Items.Assign(NBFPAServer.Connections);
end;

procedure TfrmServer.FormShow(Sender: TObject);
begin
  NBFPAServer.Open;
end;

procedure TfrmServer.NBFPAServerClientExecute(Sender: TObject; PA: TProtocolAdapter);
begin
  case PA.CurrentToken of
    CMD_CHUNK: // Dateistück eingetroffen
      begin
        if (PA.RefObject = NILthen begin // Datei schon angelegt?
          PA.RefObject := TFileStream.Create(
                            ExtractFilePath(Application.ExeName)+
                              IntToStr(frmServer.Tag)+'.txt',
                            fmCreate);
          PA.OwnsRefObject := TRUE; // beim Freigeben des PAs den FileStream auch
          frmServer.Tag := frmServer.Tag +1// Dateizähler erhöhen
        end;
        TFileStream(PA.RefObject).Write(PA.Inbound.Data[1]^, // Daten
                                        PA.Inbound.FrameSize[1]); // Menge
      end;
    CMD_STOP: // Dateitransfer beendet
      begin
        TFileStream(PA.RefObject).Free;
        PA.RefObject := NIL// Referenz entfernen
      end;
  end;
end;

procedure TfrmServer.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  NBFPAServer.Close;
end;

end.

cu
Narses


Neotracer64 - Sa 14.07.07 12:03

Danke für deine Mühen Narses. :D
Wenn ich noch Fragen habe, melde ich mich wieder hier. ;)


Narses - Mo 16.07.07 01:38

Moin!

Neue Version der Kompo (v1.10) und der Doku (v1.06), Details und Download - wie immer - im ersten Beitrag. ;)

cu
Narses


MrOuzo - Di 21.08.07 14:51

Hallo Narses,

bei mir kommt bei der Installation unter Delphi5 Ent. UpdPack.1 folgende Fehlermldung:

[Fehler] NarsesBFPA.pas(430): Eine statische Methode kann nicht überschrieben werden

dabei handelt es sich um diese QuellCodeZeile

procedure InsertObject(Index: Integer; const S: string; AObject: TObject); override;

Gruß
MrOuzo


Narses - Di 21.08.07 15:28

Moin!

user profile iconMrOuzo hat folgendes geschrieben:
bei mir kommt bei der Installation unter Delphi5 Ent. UpdPack.1 folgende Fehlermldung:
Delphi-Compiler hat folgendes geschrieben:
[Fehler] NarsesBFPA.pas(430): Eine statische Methode kann nicht überschrieben werden

dabei handelt es sich um diese QuellCodeZeile


Delphi-Quelltext
1:
procedure InsertObject(Index: Integer; const S: string; AObject: TObject); override;                    

Ich schau´s mir mal an; ich melde mich wieder (kann etwas dauern, da ich kein D5 habe; was spricht gegen D7? :?)

cu
Narses


MrOuzo - Di 21.08.07 16:09

Hi Narses,

ich hab halt leider nur D5


Gruß
MrOuzo


Narses - Di 21.08.07 21:30

Moin!

user profile iconMrOuzo hat folgendes geschrieben:
ich hab halt leider nur D5

Nunja, ich empfehle mal pauschal D7, besser ist das. :zustimm:

Mit Hilfe von user profile iconBenBE, der freundlicherweise für mich unter D5 "gesucht" hat, gibt es eine neue Version mit den notwendigen Anpassungen für D5 :arrow: wie immer im ersten Beitrag. :les: Sollte jetzt laufen. :)

cu
Narses


BenBE - Di 21.08.07 21:33

@Narses: Ob der Bug allerdings unter D4 oder D6 auch auftritt, hab ich nicht untersucht ;-)


Narses - Di 21.08.07 21:38

Moin!

user profile iconBenBE hat folgendes geschrieben:
Ob der Bug allerdings unter D4

Unterhalb von D5 supporte ich die Kompo nicht; und D5 auch nur, weil du mir dabei hilfst, sonst wäre das auch Essig. :nixweiss:

user profile iconBenBE hat folgendes geschrieben:
oder D6 auch auftritt, hab ich nicht untersucht ;-)

Ich teste die Tage mal D6, unter D7pro hab ich´s grad selbst getestet. :D

cu
Narses


MrOuzo - Mi 22.08.07 14:45

Hallo Narses, BenBE,


Superservice, danke, jetzt gehts zu installieren. Werde es dann gleich mal testen. :D

D7 werde ich auch einsetzen, habe aber noch soooo viele Kompos von D5 die ich nicht umheben möchte.


Gruß
MrOuzo


Boldar - Do 26.06.08 17:47

Hallo, Ich weiss, dass der Threat uralt ist, aber ich habe keine Ahnung, wie ich die Komponenten installieren soll. Ich benutze Delphi 2006, und da gibt es die in dem PDF beschriebenen Menüpunkte nicht. Kann mir villeicht jemand sagen, wie es geht??


Narses - Do 26.06.08 18:12

Moin!

user profile iconBoldar hat folgendes geschrieben:
aber ich habe keine Ahnung, wie ich die Komponenten installieren soll. Ich benutze Delphi 2006,
Was spricht gegen D7? Ich sehe zu D2006 keine Vorteile... :nixweiss:

user profile iconBoldar hat folgendes geschrieben:
und da gibt es die in dem PDF beschriebenen Menüpunkte nicht. Kann mir villeicht jemand sagen, wie es geht??
Du könntest probieren ein neues Package zu erstellen und die Komponenten dann da rein zu installieren. :idea:

cu
Narses


DelphiMarkus - Fr 27.06.08 08:32

Hallo!
Ich wollte das hier auch mal probieren, aber leider meldet sich bei mir AntiVir. Er meint, bei der "Server.exe" etwas gefunden zu haben.
Ist das schon bekannnt, ich habe auf die schnelle nichts darüber in diesem Thema gefunden.

Ich glaube nicht das da wirklich was dran ist.
Ich kann das Programm auch nicht starten, AntiVir verweigert das. :cry:


Narses - Fr 27.06.08 11:08

Moin!

user profile iconDelphiMarkus hat folgendes geschrieben:
Ich wollte das hier auch mal probieren, aber leider meldet sich bei mir AntiVir. Er meint, bei der "Server.exe" etwas gefunden zu haben.
Ist das schon bekannnt, ich habe auf die schnelle nichts darüber in diesem Thema gefunden.
Was für eine Server.exe? :gruebel: Mein Code und meine EXEn sind idR geprüft, wenn ich was rausgebe. Allerdings schlägt häufig die Heuristik zu, wenn man Server-Sockets in UPX-gepackten EXEn öffnet, vielleicht ist es das schon. :nixweiss:

cu
Narses


DelphiMarkus - Mo 30.06.08 08:37

Die EXE liegt unter diesem Pfad:
"TNBFPA_v111\Code\Server.exe"
AntiVir meint einen Virus oder ein anderes unerwünschtes Programm gefunden zu haben.
Hier ist der Text aus AntiVir dazu:
Zitat:

In der Datei '...\TNBFPA_v111\Code\Server.exe'
wurde ein Virus oder unerwünschtes Programm 'TR/ATRAPS.Gen' [trojan] gefunden.
Ausgeführte Aktion: Zugriff verweigern


user profile iconNarses hat folgendes geschrieben:
Mein Code und meine EXEn sind idR geprüft, wenn ich was rausgebe. Allerdings schlägt häufig die Heuristik zu, wenn man Server-Sockets in UPX-gepackten EXEn öffnet, vielleicht ist es das schon. :nixweiss:

Ich weiß es leider auch nicht...


Narses - Mo 30.06.08 09:22

Moin!

user profile iconDelphiMarkus hat folgendes geschrieben:
AntiVir meint einen Virus oder ein anderes unerwünschtes Programm gefunden zu haben.
Das ist eine False-Positive-Meldung; das ist definitiv kein Tojaner. ;) (schätze, Serversocket+UPX schlagen da zu)

Lösch das Ding einfach nach dem Auspacken und übersetz´ dir das Demoprojekt selbst nochmal neu, dann hast du das Ganze "clean". :idea:

cu
Narses


DelphiMarkus - Mo 30.06.08 09:48

Danke für den Tipp, jetzt klappt es! :zustimm:

Vielen Dank,
Maxi


Sirke - Mo 30.06.08 10:11

Hey Narses,

Danke für diese schöne Komponente! Habe bisher noch keine Bugs gefunden, außer dass meine Anti-Viren Software die Server.exe nicht mag ;-)


Finde jedoch, dass die Angabe "Verschlüsselung" ein Witz ist und man für spätere Versionen - solltest du das geplant haben - eine stärkere Verschlüsselung verwenden sollte. Außerdem wäre eine asymmetrischer Schlüsselaustauch bzw. Hybride-Verschlüsselung sinnvoll!

Zusätzlich wäre eine Daten-Kompression noch sinnvoll!


Narses - Mo 30.06.08 10:19

Moin!

user profile iconSirke hat folgendes geschrieben:
Danke für diese schöne Komponente! Habe bisher noch keine Bugs gefunden,
Danke. ;)

user profile iconSirke hat folgendes geschrieben:
Finde jedoch, dass die Angabe "Verschlüsselung" ein Witz ist [...] eine stärkere Verschlüsselung verwenden sollte
Die Komponenten verschlüsseln doch gar nix... :gruebel: sondern stellen dir Ereignisse bereit, um diese Verschlüsselung selbst in der gewünschten "stärke" auszuführen! :idea: Es liegt also allein an dir, wie "witzhaft" diese Verschlüsselung ausfällt. :nixweiss:

user profile iconSirke hat folgendes geschrieben:
Außerdem wäre eine asymmetrischer Schlüsselaustauch bzw. Hybride-Verschlüsselung sinnvoll!
Siehe oben, das ist nicht Aufgabe der Komponenten. ;)

user profile iconSirke hat folgendes geschrieben:
Zusätzlich wäre eine Daten-Kompression noch sinnvoll!
Klar wäre das sinnvoll; ist doch open-source, wir warten auf deinen Vorschlag. :)

cu
Narses


Sirke - Mo 30.06.08 11:09

user profile iconNarses hat folgendes geschrieben:
user profile iconSirke hat folgendes geschrieben:
Finde jedoch, dass die Angabe "Verschlüsselung" ein Witz ist [...] eine stärkere Verschlüsselung verwenden sollte
Die Komponenten verschlüsseln doch gar nix... :gruebel: sondern stellen dir Ereignisse bereit, um diese Verschlüsselung selbst in der gewünschten "stärke" auszuführen! :idea: Es liegt also allein an dir, wie "witzhaft" diese Verschlüsselung ausfällt. :nixweiss:

user profile iconSirke hat folgendes geschrieben:
Außerdem wäre eine asymmetrischer Schlüsselaustauch bzw. Hybride-Verschlüsselung sinnvoll!
Siehe oben, das ist nicht Aufgabe der Komponenten. ;)
Okay, habe mir das ganze nun noch einmal genauer angesehen und festgestellt, dass ich etwas voreilig war ;-) Damit wird die Komponente immer Interessanter für mich!


user profile iconNarses hat folgendes geschrieben:
user profile iconSirke hat folgendes geschrieben:
Zusätzlich wäre eine Daten-Kompression noch sinnvoll!
Klar wäre das sinnvoll; ist doch open-source, wir warten auf deinen Vorschlag. :)
Ich werde mich dran setzen. Hoffentlich müsst ihr nicht zu lange warten ;-)

MfG Sirke


BenBE - Mo 30.06.08 11:26

user profile iconSirke hat folgendes geschrieben:
user profile iconNarses hat folgendes geschrieben:
user profile iconSirke hat folgendes geschrieben:
Zusätzlich wäre eine Daten-Kompression noch sinnvoll!
Klar wäre das sinnvoll; ist doch open-source, wir warten auf deinen Vorschlag. :)
Ich werde mich dran setzen. Hoffentlich müsst ihr nicht zu lange warten ;-)

MfG Sirke

Kannst das ganze ja auch gleich als Tutorial schreiben, wie man für sowas vorgehen muss.


Narses - Do 04.09.08 20:08

Moin!

Update auf Version 1.12 der Komponente (Bugfixes), Details - wie immer - im ersten Beitrag. ;)

cu
Narses


smallsmoker - Fr 19.09.08 19:57

ich hoffe das ich mit einer bedankung (die ja eigenlich nix zum thema beiträgt) nicht gegen die foren regeln hier verstoße aber ich kann nicht anders :)
Ich finde einfach fantastisch was du hier leistest !
bitte mach weiter so !
mfg smallsmoker (der sich grad durch dein binär protokoll tut arbeitet)


Narses - Fr 19.09.08 20:17

Moin und :welcome: im Forum!

user profile iconsmallsmoker hat folgendes geschrieben:
Ich finde einfach fantastisch was du hier leistest !
Oh, danke. :beer:

user profile iconsmallsmoker hat folgendes geschrieben:
(der sich grad durch dein binär protokoll tut arbeitet)
Viel Erfolg! :zustimm:

cu
Narses


smallsmoker - Fr 19.09.08 20:30

ich habe gerade versucht TNBFPA zu installieren (also die visuellen kompos) aber leider gibt es in delphi 2007 kein "Komponente Installieren" (siehe screenshot)
ich weiß ich könnte sie auch dynamisch erzeugen aber das möchte ich nicht so gerne (bin faul -.-)
gibt es dafür eine lösung ?
mfg smallsmoker


Narses - Fr 19.09.08 20:35

Moin!

user profile iconsmallsmoker hat folgendes geschrieben:
ich habe gerade versucht TNBFPA zu installieren (also die visuellen kompos) aber leider gibt es in delphi 2007 kein "Komponente Installieren" (siehe screenshot)
Sorry, ich habe kein D2007 und kenne es daher nicht; deshalb kann ich hier nicht wirklich gut helfen... :nixweiss:

user profile iconsmallsmoker hat folgendes geschrieben:
gibt es dafür eine lösung ?
Ich habe mal gehört, dass man ein neues Package anlegen und dann die Kompos da rein installieren kann. Ob und wie das geht, keine Ahnung. :?

cu
Narses


smallsmoker - Fr 19.09.08 20:48

user profile iconsmallsmoker hat folgendes geschrieben:
Ich habe mal gehört, dass man ein neues Package anlegen und dann die Kompos da rein installieren kann. Ob und wie das geht, keine Ahnung. :?


hat perfekt geklappt damit alle was davon haben habe ich einfach ein kleines video < 1.5 mb davon gemacht wies geht :)

mfg smallsmoker


smallsmoker - Di 23.09.08 18:04

erstmal sorry für den doppelpost, ich finde es ja eingentlich ziemlich dreißt wenn leute nach fertigem code fragen aber ich hoffe du bisst mir nicht böse narses.
Also du hast ja gepostet wie man (mit minimalen mitteln) eine datei vom clienten zum server senden kann, das funktioniert auch wunderbar.
Ich habe es nun so für mich umfunktioniert das der dateiname mitgesendet wird und man auch vom server zum clienten senden kann, aber wenn der client (oder der server) während einer übertragung disconnectet gibt es ein riesiges chaos ... könntest du vieleicht (wenn du zeit und lust hast) eine ausführlichere demo (muss nich kommentiert sein) für dateiübertragung mit deiner komponente posten ?
mfg smallsmoker


Narses - Di 23.09.08 18:13

Moin!

user profile iconsmallsmoker hat folgendes geschrieben:
könntest du vieleicht (wenn du zeit und lust hast) eine ausführlichere demo (muss nich kommentiert sein) für dateiübertragung mit deiner komponente posten ?
Gibt´s doch schon [http://www.delphi-library.de/viewtopic.php?p=433259#433259]. ;)

cu
Narses


smallsmoker - Di 23.09.08 18:27

ich trau mich kaum das zu schreiben aber, da wird doch von client -> server -> client gesendet ... (die demo nach der ich gefragt habe wäre
client -> server & server -> client)
:duck: sry ich bin so faul :D, ich arbeite den mal-chat zu client -> server & server -> client selber um, mach dir keine arbeit xD
mfg smallsmoker

edit: mir ist grade noch etwas eingefallen, wie kann ich felhler die auftreten verwerfen ? so wie bei den normalen winsockets ? einfach ErrorCode = 0 ?


Narses - Di 23.09.08 21:38

Moin!

user profile iconsmallsmoker hat folgendes geschrieben:
wie kann ich felhler die auftreten verwerfen ? so wie bei den normalen winsockets ? einfach ErrorCode = 0 ?
RTFM :mrgreen: TNBFPA-Doku, Seite 10 unten... ;)

cu
Narses


smallsmoker - Sa 11.10.08 03:54

ist eigenlich eine delphi 2009 version geplant ?


Narses - Sa 11.10.08 19:52

Moin!

user profile iconsmallsmoker hat folgendes geschrieben Zum zitierten Posting springen:
ist eigenlich eine delphi 2009 version geplant ?
Nein.

Ich will ganz ehrlich sein: ich habe ein D7pro gekauft und bezweifle sehr, dass ich jemals wieder Geld für eine andere/neuere (Delphi-)Version ausgeben werde. :| Wenn mein Code mit neueren Delphi-Versionen kompatibel ist, dann ist das schön. :) Wenn nicht, Pech gehabt. :nixweiss: Zum Win32-Programmieren reicht D7pro mehr als aus.

cu
Narses


Narses - Mo 01.03.10 00:21

Moin!

Dank eines kleinen Tricks war die Umstellung auf D2010 (D2k9 empfehle ich nicht, das ist unicode-mäßig noch zu buggy) gar nicht so viel Arbeit, wie gedacht. :nixweiss:

Es gibt also jetzt eine D2010-fähige Version zum Download im ersten Beitrag. ;)

cu
Narses


matze - Mo 01.03.10 09:59

user profile iconNarses hat folgendes geschrieben Zum zitierten Posting springen:
(D2k9 empfehle ich nicht, das ist unicode-mäßig noch zu buggy)

Inwiefern das?


Narses - Mo 01.03.10 13:48

Moin!

user profile iconmatze hat folgendes geschrieben Zum zitierten Posting springen:
user profile iconNarses hat folgendes geschrieben Zum zitierten Posting springen:
(D2k9 empfehle ich nicht, das ist unicode-mäßig noch zu buggy)
Inwiefern das?
Insofern dass Methoden AnsiStrings entgegen nehmen und Unicode-Strings abliefern (.SendText/.ReceiveText) oder dass einige AnsiXxx-Funktionen Unicode-Strings zurückgeben (OK, das gilt auch für D2010). :nixweiss: Ich kann user profile iconMartok nur zustimmen, eine Umstellung, bei der die VCL inkompatibel zu sich selbst wird, naja... :|

cu
Narses


Daniel775 - Do 15.09.11 19:45

Guten Abend allerseits.

Bin durch Zufall auf diesen Thread gestossen und wollte mal fragen, ob ich hier richtig bin. Ich würde gerne Einstellungen von einem Clientprogramm zum Serverprogramm schicken.
In anderen Threads hab ich gelesen, das man keine records wählen sollte um das zu realisieren bzw. man sollte keine records über das socket schieben. Weil man nie weiss was, wann, wieviel ankommt.
Ist es mit diesem Protokoll hier realisierbar?
Das ich beim clienten ein record in ein Memorystream verpacke diesen über das Socket zum Server schicke und der Server aus dem stream wieder ein record macht.

Hoffe auf zahlreiche Reaktionen und evtl Beispiele ...


Narses - Do 15.09.11 22:56

Moin und :welcome: in der Entwickler-Ecke!

user profile iconDaniel775 hat folgendes geschrieben Zum zitierten Posting springen:
Ich würde gerne Einstellungen von einem Clientprogramm zum Serverprogramm schicken.
Grundsätzlich geht das, ja. ;)

user profile iconDaniel775 hat folgendes geschrieben Zum zitierten Posting springen:
In anderen Threads hab ich gelesen, das man keine records wählen sollte um das zu realisieren bzw. man sollte keine records über das socket schieben. Weil man nie weiss was, wann, wieviel ankommt.
user profile iconDaniel775 hat folgendes geschrieben Zum zitierten Posting springen:
Das ich beim clienten ein record in ein Memorystream verpacke
Das Problem ist das Serialisieren des records, nicht das Transportieren eines Bytestreams. :idea:

user profile iconDaniel775 hat folgendes geschrieben Zum zitierten Posting springen:
Ist es mit diesem Protokoll hier realisierbar?
Solange da ein record im Spiel ist, wird das mit jeder Transportart Probleme geben. :nixweiss: Die Kunst ist also die Vermeidung des records, nicht der Einsatz des Protokolls (da kommst du eh nicht drum rum, irgendwie musst du die Daten ja wieder auseinanderpflücken). :)

user profile iconDaniel775 hat folgendes geschrieben Zum zitierten Posting springen:
diesen über das Socket zum Server schicke und der Server aus dem stream wieder ein record macht.
Ganz anderer Ansatz (sofern du auf dieser Kompo aufsetzen willst): Mach aus deinen Einstellungen ein Objekt, diesem verpasst du eine Methode, welche die Eigenschaften an ein TCmdSeq-Objekt übergeben kann. Dann brauchst du noch eine Methode, welche die Eigenschaften wieder aus einem Protokolladapter lesen kann. Dann sollte das klappen.

cu
Narses


Daniel775 - Do 15.09.11 23:17

Hallo Narses,

danke für deine Antwort.

Zitat:

Mach aus deinen Einstellungen ein Objekt


Sollte kein Problem sein.

Zitat:

diesem verpasst du eine Methode


Ist auch kein Problem

Zitat:

welche die Eigenschaften an ein TCmdSeq-Objekt übergeben kann


Da wird es hapern. Ich hab mir die .add Procedure mal angesehen. Ich kann da kein Objekt übergeben, oder? Wie kann ich da ansetzen?

Zitat:

Dann brauchst du noch eine Methode, welche die Eigenschaften wieder aus einem Protokolladapter lesen kann


Die Frage die ich mir da stelle ist, wie kommt das Objekt dann im Adapter an um es abzuholen?


Narses - Do 15.09.11 23:30

Moin!

user profile iconDaniel775 hat folgendes geschrieben Zum zitierten Posting springen:
Da wird es hapern. Ich hab mir die .add Procedure mal angesehen. Ich kann da kein Objekt übergeben, oder? Wie kann ich da ansetzen?
Der "Witz" an dem TCmdSeq-Objekt ist ja, dass es keine strukturierten Daten annimmt, sondern immer nur einfache Datentypen. Kennst du die Methode und das Konzept von TPersistent.Assign() und .AssignTo()? Hier ist das genau so: in der Methode, die das Objekt übergeben soll gehst du jede Eigenschaft durch und schreibst sie in das TCmdSeq-Objekt. Das ist die einzige Möglichkeit bei einer Änderung des Objekts keinen Datenmatsch zu produzieren. Ändert sich das Objekt, muss auch ein entsprechend geändertes Transport-Verfahren benutzt werden (hier: ein anderes Token).

Alternative wäre die Delphi-eigene Methode zum De-/Serialisieren von Objekte, so wie es die VCL/IDE mit den Komponenten tut. Ist aber bischen frickelig. :?

Noch ein anderer Ansatz ist die Transformation in das INI-Format, dieses als Text transportieren und auf der anderen Seite wieder aus dem INI-Format lesen.

Du merkst schon, egal was man macht, wenn man einfach nur "auf der einen Seite rein und auf der anderen genau so wieder raus" haben will, geht das gar nicht so einfach... jedenfalls nicht, wenn es "sauber" sein soll. :nixweiss:

cu
Narses


Daniel775 - Fr 16.09.11 13:38

Zitat:
...gehst du jede Eigenschaft durch und schreibst sie in das TCmdSeq-Objekt.


Das heisst Praktisch für jede Eigenschaft in meinem Objekt ein neues Token und wenn sich die Eigenschaft oder das Objekt verändert diesse Änderung wieder über die Methode an das TCmdSeq-Objekt schicken. Hab ich das richtig verstanden?

Ich mache das im Moment mit einer .ini Datei. Und suche jetzt eine Client <> Server Lösung. Das würde bedeuten, das auch das Terminatorzeichen Protokoll für diese Aufgabe völlig ausreichend wäre!?


Narses - Fr 16.09.11 13:59

Moin!

user profile iconDaniel775 hat folgendes geschrieben Zum zitierten Posting springen:
Zitat:
...gehst du jede Eigenschaft durch und schreibst sie in das TCmdSeq-Objekt.
Das heisst Praktisch für jede Eigenschaft in meinem Objekt ein neues Token und wenn sich die Eigenschaft oder das Objekt verändert diesse Änderung wieder über die Methode an das TCmdSeq-Objekt schicken. Hab ich das richtig verstanden?
Ähm, nein. :? Machen wir mal ein Beispiel:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
type
  TSettings = class(TObject)
  private
    FStr: String;
    FInt: Integer;
  public
    function AsCmdSeq: TCmdSeq;
    property Str: String read FStr write FStr;
    property Int: Integer read FInt write FInt;
  end;

  TForm1 = class(TForm)
    NBFPAClient1: TNBFPAClient;
    NBFPAServer1: TNBFPAServer;
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
    procedure NBFPAServer1ClientExecute(Sender: TObject; PA: TProtocolAdapter);
  public
    Settings: TSettings;
  end;

implementation

function TSettings.AsCmdSeq: TCmdSeq;
begin
  Result := TCmdSeq.Create(123); // das hier ist die Version 123 der Einstellungen
  Result.Add(FStr); // Eigenschaften schreiben
  Result.Add(FInt);
  //...
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  NBFPAClient1.SendAndFree(Settings.AsCmdSeq);
end;

procedure TForm1.NBFPAServer1ClientExecute(Sender: TObject; PA: TProtocolAdapter);
begin
  case PA.CurrentToken of
    123// Einstellungen in Version 123 angekommen
      begin
        Settings.Str := PA.Inbound.Strings[1]; // in der gleichen Reihenfolge wieder zuweisen
        Settings.Int := PA.Inbound.AsInt[2]; // wie geschrieben wurde
        //...
      end;
    122// Einstellungen in Version 122 angekommen (veraltet)
      begin
        Settings.Str := PA.Inbound.Strings[1]; // hier gabs nur den String, der Int war noch nicht bekannt
        //...
      end;
  end;
end;


user profile iconDaniel775 hat folgendes geschrieben Zum zitierten Posting springen:
Ich mache das im Moment mit einer .ini Datei. Und suche jetzt eine Client <> Server Lösung. Das würde bedeuten, das auch das Terminatorzeichen Protokoll für diese Aufgabe völlig ausreichend wäre!?
Jedes Protokoll ist für die Übertragung geeignet, egal welches. Damit wird ja nur Transportiert. Wie du die Einstellungen verwaltest, also als Objekt, Record, INI-Text, etc. ist doch davon unabhängig. :nixweiss:
Um die Frage zu beantworten: ja, das Terminatorzeichen-Protokoll wäre dafür auch ausreichend. ;)

Machen wir das mal anders: was soll das denn werden und worauf legst du Wert bei der Sache? :lupe:

cu
Narses


Daniel775 - Fr 16.09.11 20:20

Zitat:

Machen wir das mal anders: was soll das denn werden und worauf legst du Wert bei der Sache?


Mein aktuelles Projekt ist eine Datenbankgestützte Zeiterfassung. Oder einfach gesagt, eine Stempeluhr. Mit Mitarbeiter, Urlaubs -und Fehlzeitenverwaltung. Es gibt ein UserFront-End als eigenständiges Programm wo halt eingestempelt wird und ein Admintool. Das Admintool möchte ich halt mit gewissen Funktionen ausstatten.
Wartungsmodus ein/aus, Anzeigedauer der letzten Einstempelungen usw.
Diese möchte ich mittels Client/Serververbindung an die Stempeluhr schicken. In Form einer Datei die dann beim start immer eingelesen wird. Dein Beispiel wird mir sehr helfen das umzusetzen .... vielen lieben Dank. :D
Das mit den Versionen in der ClientExecute Procedure gefällt mir und ist ein sehr guter Tipp.

Grüße


Martok - Di 06.03.12 00:13

Hallo,

ich baue momentan ein RPC-Interface rund um NBFPA. Das ganze läuft so ab, dass man dann z.B. ein OnEntityCall-Event bekommt, mit den Parametern: (Connection, EntityRef, Function, Parameter). Die kann man dann in Anwendungs-Code weiterverteilen an die richtigen Handler.
Das Problem ist jetzt, die Parameter richtig zu zerpflücken. Wenn ich einfach nur die TInboundFrameList übergebe, ist das unhandlich, da ja die ersten paar Argumente "intern" sind: Entity,FunctionCode etc.

Einfach die verarbeiteten ArgumentFrames aus der Liste löschen (damit die Paremter vorwandern) geht nicht, das kollidiert mit der NBFPA-Internen Verarbeitung. Ich würde die also gerne vorher zerpflücken und eventuell in ein Array of Const oder Variant reinschieben. Das ist an sich auch okay, aber die Überdeckung der damit darstellbaren Datentypen zu den mit NBFPA übertragbaren Formate ist gelinde gesagt gering. Selbst mit Auto-Konvertierung (Datentypen kann man ja mitsenden) wird das entweder nicht einfach oder bandbreitentechnisch eher schlecht.

Hat mit sowas jemand Erfahrung? Ich bin auch für Alternativkonzepte immer offen. Alles, was im Endeffekt einfach zu verwenden ist.


Narses - Mi 07.03.12 00:54

Moin!

An einem Stück Dispatcher-Code im OnExecute oder einer auf´s Nötige reduzierten Kopie der Parameter aus der InboundFrameList wird wohl irgendwie kein Weg vorbeiführen... :nixweiss:

Aber, ehrlich gesagt, mir ist sowieso schleierhaft, wie du den Methoden-Call (abstrahiert) "durchreichen" willst. :gruebel: Das geht doch immer nur für bekannte Methoden, oder klemmt mir da wieder ein Synapse? :lupe:

cu
Narses


BenBE - Mi 07.03.12 01:04

*Mit Zaun wedel* array of const AKA array of TVarRec :mrgreen:


Martok - Mi 07.03.12 01:16

Hallo, danke für die Antwort.
Ja, Dispatcherkrams ist da. Geht nur noch darum wie die aussehen soll ;)
Kurzfassung: es gibt z.B. auf dem Client eine Funktion:
EntityCall(EntityID: Cardinal; Function: Word; Params: ????).
Die baut daraus eine TCmdSeq mit PacketID ENTITY_CALL und den Argumenten EntityID, Function, Param1, Param2, ..., ParamN
Auf dem Server wird im OnExecute das zerpflückt und ein OnEntityCall(Entity, Func, ???) aufgerufen.
Dort bindet der User seinen Dispatcher zu den Entities an und diese wiederum machen dann je nach Function-Code was.

Die Parameter kann man als array of const reinschieben und auf der anderen Seite wieder so parsen. Das geht, Problem ist, dass da nur eine kleine Auswahl von Datentypen möglich ist. Byte/Word/Cardinal/Integer ist da alles eins. Variant wäre weniger problematisch, aber es passt immer noch nicht alles (Extended fehlt und ByteArrays z.B. sind sehr seltsam).
Ich hab schon überlegt, Parameterobjekte zu nehmen, die sich selbst serialisieren. Ohne anonyme Klassen (Hallo, Java) bedeutet das aber, dass haufenweise Klassen zu deklarieren und zu implementieren sind. Ich will ja grade sowas vereinfachen, nicht eine "Menge Code" durch eine andere "Menge Code" erledigen.
Wenn Delphi assoziative Arrays mit TypInfo hätte... *träum* :roll:



user profile iconBenBE hat folgendes geschrieben Zum zitierten Posting springen:
Mit Zaunpfahl wedel* array of const AKA array of TVarRec :mrgreen:
Lesen. Hirn anschalten. Nochmal lesen. Dann vielleicht posten.


Narses - So 11.03.12 03:33

Moin!

Jaa, nach intensivem Überlegen ;) würde ich zu einer (weiteren, nur für die Weiterverarbeitung benötigten) TInboundFrameList als Parameter-Konvention raten, eben genau so, wie es auch reinkommt, datentypenfrei. Das hat zwar den doofen "Nachteil", dass du dann die Parameter jedes mal kopieren musst, das sollte aber nicht so schlimm sein, da die Strings auf dem Heap ja referenzgezählt sind und nicht dupliziert werden sollten. Damit "überlässt" du ja quasi der Zielmethode die Wahl, was das für Parameter und wie sie handzuhaben sind. :idea: :nixweiss: Sobald du das typensicher haben willst, wird das mit Delphi wohl nicht so lustig werden... :?

Also kurz: OnEntityCall(Entity, Func, Params: TInboundFrameList)

cu
Narses