Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Netzwerke (https://www.delphipraxis.net/14-netzwerke/)
-   -   Delphi TClientSocket auf Datenmodul (https://www.delphipraxis.net/165939-tclientsocket-auf-datenmodul.html)

Jens Hartmann 23. Jan 2012 06:59

TClientSocket auf Datenmodul
 
Guten Morgen zusammen,

ich habe ein eher seltsames Problem mit meinem Delphi XE2. Ich möchte eine Komponente TClientSocket auf einem Datenmodul plazieren.
(TClientSocket und TServerSocket zuvor natürlich nachinstalliert).

Ziehe ich die Komponente direkt auf eine Form, funktioniert das. Will ich die Komponente auf ein Datenmodul legen, kann ich Sie in der Toolpalette nicht finden.

Lege ich die TClientSocket auf eine Form, kopiere die Kompo und füge Sie im Datenmodul ein, kommt die Fehlermeldung

"Klasse TClientSocket nicht gefunden"

Kennt das Problem jemand?

Vorab Danke und Gruß Jens

Furtbichler 23. Jan 2012 07:30

AW: TClientSocket auf Datenmodul
 
Workaround: Im DataModuleCreate instantiieren.

Jens Hartmann 23. Jan 2012 19:07

AW: TClientSocket auf Datenmodul
 
Zitat:

Zitat von Furtbichler
Workaround: Im DataModuleCreate instantiieren.

Versteh ich um ehrlich zu sein nicht. Auch Google ist hier scheinbar nicht mein Freund.

Furtbichler 23. Jan 2012 19:18

AW: TClientSocket auf Datenmodul
 
Delphi-Quellcode:
Procedure TMyDataModule.DataModuleCreate(Sender : TOBject);
Begin
  MyClientDataset := TClientDataset.Create(Nil);
  MyClientDataset..... // Properties setzen
end;

Procedure TMyDataModule.DataModuleDestroy(Sender : TObject);
Begin
  MyClientDataset.Free;
End;

Sir Rufo 23. Jan 2012 19:27

AW: TClientSocket auf Datenmodul
 
und warum nicht einfach
Delphi-Quellcode:
Procedure TMyDataModule.DataModuleCreate(Sender : TOBject);
Begin
  MyClientDataset := TClientDataset.Create( Self );
  MyClientDataset..... // Properties setzen
end;
Dann kümmert sich das DataModul selber um die Freigabe ;)

Beobachtet habe ich das auch schon und als Workaround probier mal folgendes aus:
  1. Ziehe auf ein Formular die gewünschte Komponente
  2. Die Komponente von der Form auswählen und mit STRG-X ausschneiden
  3. Auf das DatenModul wechseln und mit STRG-V dort einfügen
  4. Alles speichern
Jetzt sollten auch alle nicht-visuellen Komponenten auswählbar sein :)

Furtbichler 23. Jan 2012 20:29

AW: TClientSocket auf Datenmodul
 
Zitat:

Zitat von Sir Rufo (Beitrag 1147308)
und warum nicht einfach
Delphi-Quellcode:
Procedure TMyDataModule.DataModuleCreate(Sender : TOBject);
Begin
  MyClientDataset := TClientDataset.Create( Self );
  MyClientDataset..... // Properties setzen
end;
Dann kümmert sich das DataModul selber um die Freigabe ;)

Das widerspricht dem Designtemplate: "Wer's anfordert, gibts wieder frei". Ansonsten haste Recht.

Sir Rufo 23. Jan 2012 21:34

AW: TClientSocket auf Datenmodul
 
Zitat:

Zitat von Furtbichler (Beitrag 1147320)
Zitat:

Zitat von Sir Rufo (Beitrag 1147308)
und warum nicht einfach
Delphi-Quellcode:
Procedure TMyDataModule.DataModuleCreate(Sender : TOBject);
Begin
  MyClientDataset := TClientDataset.Create( Self );
  MyClientDataset..... // Properties setzen
end;
Dann kümmert sich das DataModul selber um die Freigabe ;)

Das widerspricht dem Designtemplate: "Wer's anfordert, gibts wieder frei". Ansonsten haste Recht.

Hmmm, mal überlegen wer denn jetzt wer ist ... IMHO ist hier "wer" ja die Instanz von TMyDataModule.
Wenn ich also der erzeugten Instanz vom ClientDataSet als Owner die Instanz von TMyDataModule mitgebe, so ist das nicht nur möglich, sondern auch noch in jeder Hinsicht richtig.

Somit sehe ich es hier in diesem (speziellen) Fall keinen Widerspruch zum Designtemplate, denn der übergebene Owner ist auch derjenige, der es angefordert hat :)

Furtbichler 24. Jan 2012 06:38

AW: TClientSocket auf Datenmodul
 
Es geht aus dem Code nicht hervor, das MyClientDataset ordentlich freigegeben wird. Um den Code zu verstehen, muss ich in fremden Code nachschauen, wobei sich hier Probleme ergeben:
* Habe ich den Quelltext? (hat nicht jeder)
* Existiert ein Manual? (ja ja, F1)
* Wird da wirklich etwas freigegeben? (hoffen wir mal)
Ich muss also ganz schöne Klimmzüge anstellen, um zu verifizieren, das das Objekt freigegeben wird. => Unnötige Arbeit => schlecht lesbar => schlecht wartbar.

Das sind nicht gerade Argumente für deine Version (aus Sicht der Lesbarkeit).

Von der Orthogonalität der verwendeten Klassen her hast Du natürlich Recht: "Das wird überall in der VCL so gemacht, der Designer machts auch, also mach ich es auch. Und das ist auch gut so". Ein versierter Leser des Codes, der vorher anderen VCL-Code gelesen hat, wird diese implizite (eigentlich: versteckte) Freigabe erkennen. Wir programmieren aber im Idealfall nicht für Gurus.

Sir Rufo 24. Jan 2012 07:08

AW: TClientSocket auf Datenmodul
 
Zitat:

Zitat von Furtbichler (Beitrag 1147332)
Es geht aus dem Code nicht hervor, das MyClientDataset ordentlich freigegeben wird. Um den Code zu verstehen, muss ich in fremden Code nachschauen, wobei sich hier Probleme ergeben:
* Habe ich den Quelltext? (hat nicht jeder)
* Existiert ein Manual? (ja ja, F1)
* Wird da wirklich etwas freigegeben? (hoffen wir mal)
Ich muss also ganz schöne Klimmzüge anstellen, um zu verifizieren, das das Objekt freigegeben wird. => Unnötige Arbeit => schlecht lesbar => schlecht wartbar.

Eine wesentliche Eigenschaft der Klasse TComponent ist die Owner-Beziehung, die im Wesentlichen u.a. dafür sorgt, dass der Owner einer TComponent-Instanz die Freigabe veranlasst, wenn der Owner freigegeben wird.
Man könnte also fast behaupten, dass ein Großteil der Daseinsberechtigung von TComponent aus diese Owner-Beziehung besteht.
Die Klasse TComponent selbst ist eine der wesentlichen Basis-Komponenten der VCL.

Deiner Argumentation folgend und weitergedacht, dürfte ich auch keine TStrings benutzen, weil ich ja nicht weiß, ob die Strings wirklich gespeichert werden (ich müsste dort auch erst mal den Quelltext sichten, und wenn ich den nicht habe ...)
Eigentlich dürfte ich keine Komponenten verwenden ... alles selber programmieren.

Ein weiteres Kriterium, für die Angabe eines Owners, ist der einfachere Zugriff auf die Komponenten über das Components-Array des Owners.
Dieses funktioniert aber nur, wenn ich den Owner bei der Instanz-Erzeugung mit angebe.
Und wenn ich den Owner angebe, dann habe ich - as designed - die Verantwortung für die Freigabe delegiert, an den Owner.

Wer dieses dann im Code nicht versteht, der sollte sich auch den Gefallen tun und den Editor ganz schnell wieder schließen, denn es fehlen die existentiellen Grundlagen für die VCL. ;)

@all: Wenn diese Diskussion hier nervt, dann nur Bescheid geben - wir führen dies dann per PN weiter :)

Furtbichler 24. Jan 2012 07:37

AW: TClientSocket auf Datenmodul
 
Ich sagte ja bereits, das man das so schreiben kann, wenn man unterstellt, das der Leser die VCL und ihre Eigenheiten kennt.
Zitat:

Zitat von Sir Rufo (Beitrag 1147333)
Deiner Argumentation folgend und weitergedacht, dürfte ich auch keine TStrings benutzen, weil ich ja nicht weiß, ob die Strings wirklich gespeichert werden

Das ist nicht weitergedacht, sondern um-die-Ecke-gedacht, denn: Die Funktionalität einer Klasse ist etwas anderes als ihre Seiteneffekte. Und die Tatsache, das ein TComponent-Derivat vom Owner freigegeben wird, ist ein nicht im Code dokumentierter Seiteneffekt (ja gut'eh, Seiteneffekte sind vom Wesen her nicht dokumentiert).
Zitat:

...Wer dieses dann im Code nicht versteht, der sollte .. den Editor ganz schnell wieder schließen...
So kann man sich auch aus der Affäre ziehen.

So, wenn man die sinnvollen Argumente mal gegenüberstellt, dann ergibt sich das gleiche Bild wie eben (imho):
Einerseits (ohne Owner) eine bessere Lesbarkeit für Leute, die die VCL nicht in- und auswendig kennen (also mich z.B. ;-) ), andererseits eine im Design der VCL verankerte Verwendung (mit Angabe des Owners) mit praktischen Vorteilen.

Hier ist es imho blöd, das man entweder das eine, oder das andere bekommt, aber nicht beides. Obwohl....

Was passiert, wenn ich MyClientDataset freigebe? Sagt es dem Owner nicht: "Schmeiss mich aus deiner Liste raus"?

Dann könnte ich ja den Owner mit angeben und (wenn ich denn unbedingt will) das Objekt trotzdem explizit freigeben. Damit könnte man die Diskussion im Konsens schließen und sich wieder der Programmierung von diesem dusseligen Suchdingsda widmen, das sowieso keiner braucht. Wie hast Du das doch gleich genannt? "Gugl"?

DeddyH 24. Jan 2012 07:44

AW: TClientSocket auf Datenmodul
 
Da man Workarounds ja IMO sowieso tunlichst kommentieren sollte kann man ja gleich dazu schreiben, wieso entweder kein Owner angegeben wurde oder keine explizite Freigabe erfolgt und ist somit aus dem Schneider ;)

Sir Rufo 24. Jan 2012 07:56

AW: TClientSocket auf Datenmodul
 
Ich sehe eben dieses Freigeben durch den Owner nicht als Seiteneffekt, sondern als Funktionalität - und eben eine Basis-Funktionalität an. Benutzt du keine Formulare, auf denen ein paar visuelle Komponenten platziert sind (TEdit, etc.)?
Wo ist da im Code dokumentiert, dass die überhaupt erzeugt werden, geschweige denn freigegeben? ;)

Natürlich kann man eine Komponente auch wieder explizit freigeben, denn diese meldet ihrem Owner, dass sie sich jetzt mal vom Acker macht ... schön ist es nicht, aber es funktioniert.

Eigentlich gibt man den Owner an, wenn die Lebensdauer der Komponente vom Owner abhängen soll.
Und praktisch ist das in dem Falle auch, weil man sich einen Speicher (Liste) mit den Komponenten und die Freigabe-Orgie am Ende spart.
Das ist somit für faule Programmierer wie mich gemacht worden


Zitat:

Zitat von DeddyH (Beitrag 1147336)
Da man Workarounds ja IMO sowieso tunlichst kommentieren sollte kann man ja gleich dazu schreiben, wieso entweder kein Owner angegeben wurde oder keine explizite Freigabe erfolgt und ist somit aus dem Schneider ;)

Ich habe ja schon einen Workaround angegeben, wo am Ende der normale RAD-Ansatz wieder funktioniert - Komponenten-Drauf-Klatschen :)

Medium 24. Jan 2012 08:19

AW: TClientSocket auf Datenmodul
 
Mal eine ganz andere Frage: Soweit ich weiss, arbeiten Sockets (zumindest die Delphi-Dinger) mit Fensterhandles bzw. Messages. Wenn man sowas auf ein DM steckt, kommen dann die Events und alles überhaupt an?

Jens Hartmann 24. Jan 2012 14:20

AW: TClientSocket auf Datenmodul
 
Zitat:

Zitat von Medium
Mal eine ganz andere Frage: Soweit ich weiss, arbeiten Sockets (zumindest die Delphi-Dinger) mit Fensterhandles bzw. Messages. Wenn man sowas auf ein DM steckt, kommen dann die Events und alles überhaupt an?

Ich bin gerade nicht ganz sicher, aber irgendwo habe ich sogar gelesen, das man die Sockets auf ein Datenmodul legen kann. Außerdem hat es bisjetzt mit D2007 ja auch wunderbar funktioniert.

Der Vorteil ist, ich kann von jedem Formular geziehlt auf die TClientSocket zugreifen. Wenn ich diese ins MainForm lege, müsste ich ja mit Querverweisen arbeiten.


Delphi-Quellcode:
uses
  IrgendeineForm;
....

implementation //von Irgendeiner Form

uses
  MainForm;
Beim Datenmodul,kann ich jeweils auf diese zugreifen, kann vor dem Programmstart schon die Serververbindung herstellen.
Daher gesehen, sollte nichts dagegen sprechen.

Ich versteh allerdings nicht, warum ich die Komponenten nicht auf das Datenmodul gelegt bekomme.

Allerdings, nach dem ich die genannten Tips umgesetzt habe, funktioniert es.

Bevor ich einen neuen Thread starte, mal kurz eine andere Frage.
Die Verlegung auf ein Datenmodul ist durch eine zukünftig gewollte Authentifizierung auf dem Server entstanden.
Ich muss also vor dem Start der Anwendung erst prüfen, ob meine Benutzerdaten dem Server bekannt sind. Daher habe ich das ganze auf ein DM verschoben und erstelle dieses vor meinem Anmeldebildschirm. Daher kann ich die Userabfrage direkt auf dem Server machen.

Delphi-Quellcode:
begin
  Application.CreateForm(TDataModule5, DataModule5);
  if Login.Execute then
    begin
      Application.Initialize;
      Application.MainFormOnTaskbar := True;
      Application.CreateForm(TForm4, Form4);
      Application.Run;
    end
  else
    ShowMessage('Fehler bei der Anmeldung, Programm wird beendet!');
end.
Mir stellt sich nun die Frage, ob ich eventuell grundsätzlich eine andere Komponente als die TServer und ClientSocket verwenden sollt. Gibt es irgendeine Komponente die den direkten Uservergleich kann. Oder muss ich das immer selber schreiben.

So mit Protokolldatei etc...

Ich weiß wie das geht, aber wenn ich z.B. beim Start des Servers der TServerSocket(Ähnliche Kompo) die Authentifizierungsdaten zur Verfügung stellen könnte, z.B. UserName = User Password = Password und beim Connect dieses geprüft würde, wäre das für meinen Fall völlig ausreichend und nicht so aufwendig. Gibt es so eine Komponente?

Gruß Jens

mjustin 24. Jan 2012 14:31

AW: TClientSocket auf Datenmodul
 
Zur ursprünglichen Frage - kann es das gleiche Feature (aus XE2) sein, das in diesem Blogartikel beschrieben wird?

XE2: TDatamodule v TImageList, TActionList, TTimer etc.
http://jed-software.com/blog/?p=504

Ursache des "Problems" ist die Einführung einer neuen Property, "ClassGroup", die steuert, welche Komponenten beim Design eines Datamoduls in der Palette sichtbar / verwendbar sind. Es geht dabei um die Zuordnung zu bestimmten Frameworks (FireMonkey, VCL).

TClientSocket ist wahrscheinlich nur unter VCL nutzbar. Ich tippe, dass Indy TCP/IP Komponenten direkt (ohne Änderung der ClassGroup) auf ein Datenmodul geworfen werden können.

Jens Hartmann 24. Jan 2012 15:07

AW: TClientSocket auf Datenmodul
 
Zitat:

Zitat von mjustin
TClientSocket ist wahrscheinlich nur unter VCL nutzbar. Ich tippe, dass Indy TCP/IP Komponenten direkt (ohne Änderung der ClassGroup) auf ein Datenmodul geworfen werden können.

Werde ich heute Abend mal ausprobieren...

Gruß Jens

shmia 24. Jan 2012 16:10

AW: TClientSocket auf Datenmodul
 
Zitat:

Zitat von Jens Hartmann (Beitrag 1147397)
Ich versteh allerdings nicht, warum ich die Komponenten nicht auf das Datenmodul gelegt bekomme.

Weil es kein aktives Designtime Package auf deinem Rechner gibt, das die Komponente(n) einbindet.
Du müsstest dclsocket100.bpl einbinden; Die "100" bezeichnet die Delphiversion und kann bei dir einen anderen Wert haben.

Jens Hartmann 24. Jan 2012 16:21

AW: TClientSocket auf Datenmodul
 
Zitat:

Zitat von shmia
Weil es kein aktives Designtime Package auf deinem Rechner gibt, das die Komponente(n) einbindet.
Du müsstest dclsocket100.bpl einbinden; Die "100" bezeichnet die Delphiversion und kann bei dir einen anderen Wert haben.

Natürlich habe ich das. Bei mir ist das die dclsocket160.bpl.

Gruß Jens

Jens Hartmann 25. Jan 2012 10:08

AW: TClientSocket auf Datenmodul
 
Zitat:

Zitat von mjustin
Zur ursprünglichen Frage - kann es das gleiche Feature (aus XE2) sein, das in diesem Blogartikel beschrieben wird?

XE2: TDatamodule v TImageList, TActionList, TTimer etc.
http://jed-software.com/blog/?p=504

Ursache des "Problems" ist die Einführung einer neuen Property, "ClassGroup", die steuert, welche Komponenten beim Design eines Datamoduls in der Palette sichtbar / verwendbar sind. Es geht dabei um die Zuordnung zu bestimmten Frameworks (FireMonkey, VCL).

TClientSocket ist wahrscheinlich nur unter VCL nutzbar. Ich tippe, dass Indy TCP/IP Komponenten direkt (ohne Änderung der ClassGroup) auf ein Datenmodul geworfen werden können.

Jawohl, so ist es. Die Indy´s gehen.

Gibt es da gravierende Unterschiede zwischen der

TServerSocket - TIdTCPServer

und der...

TClientSocket - IdTCPClient

Gruß Jens


Alle Zeitangaben in WEZ +1. Es ist jetzt 12:32 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz