AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Netzwerke Delphi Grundsatz Fragen Client/Server Anw. via Indy10
Thema durchsuchen
Ansicht
Themen-Optionen

Grundsatz Fragen Client/Server Anw. via Indy10

Ein Thema von TUX_der_Pinguin · begonnen am 23. Apr 2009 · letzter Beitrag vom 24. Apr 2009
Antwort Antwort
TUX_der_Pinguin

Registriert seit: 1. Jun 2005
Ort: Anholt (NRW)
608 Beiträge
 
Delphi 11 Alexandria
 
#1

Grundsatz Fragen Client/Server Anw. via Indy10

  Alt 23. Apr 2009, 14:02
Ich beschäftige mich grade mit dem Thema Client-Server Anwendung mit den Komponenten (IdTCPServer, IdTCPClient) aus der
Indy Sammlung von Delphi 2007 Prof.

Ich habe einen Server und einen Client erstellt, am Server können sich ein oder mehre Clients "anmelden" Die Clients können
auch einfache Text nachrichten Verschicken, soweit kein Problem.

Server:
Delphi-Quellcode:
unit uSrvMain;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, IdBaseComponent, IdComponent, IdCustomTCPServer, IdTCPServer,
  StdCtrls, IdContext, DateUtils, Buttons;

type
  tClient = record
    Host : String;
    Port : Integer;
  end;

type
  TForm1 = class(TForm)
    Memo1: TMemo;
    edtCommand: TEdit;
    Label1: TLabel;
    btnSend: TButton;
    IdTCPServer: TIdTCPServer;
    ltbClients: TListBox;
    Label2: TLabel;
    ComboBox1: TComboBox;
    Label3: TLabel;
    procedure IdTCPServerConnect(AContext: TIdContext);
    procedure IdTCPServerDisconnect(AContext: TIdContext);
    procedure IdTCPServerExecute(AContext: TIdContext);
    procedure FormCreate(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
  //init
  IdTCPServer.Active := False;
  IdTCPServer.Bindings.Clear;

  //Einstellungen
  IdTCPServer.DefaultPort := 666;
  try
    IdTCPServer.Active := True;
  except
    Raise;
  end;

  Caption := 'Server - Online';

end;

procedure TForm1.IdTCPServerConnect(AContext: TIdContext);
begin
  Memo1.Lines.Add('Connect: '+AContext.Binding.PeerIP);
end;

procedure TForm1.IdTCPServerDisconnect(AContext: TIdContext);
begin
  Memo1.Lines.Add('Disconnect: '+AContext.Binding.PeerIP);
end;

procedure TForm1.IdTCPServerExecute(AContext: TIdContext);
begin
  Memo1.Lines.Add('Message: '+AContext.Connection.IOHandler.ReadLn);
end;

end.

Client:
Delphi-Quellcode:
unit uClMain;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, IdBaseComponent, IdComponent, IdTCPConnection, IdTCPClient, StdCtrls;

type
  TForm2 = class(TForm)
    btnConnect: TButton;
    btnDisconnect: TButton;
    IdTCPClient: TIdTCPClient;
    Label1: TLabel;
    edtCommand: TEdit;
    btnSend: TButton;
    Memo1: TMemo;
    Label2: TLabel;
    procedure FormCreate(Sender: TObject);
    procedure btnConnectClick(Sender: TObject);
    procedure btnDisconnectClick(Sender: TObject);
    procedure btnSendClick(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form2: TForm2;

implementation

{$R *.dfm}

procedure TForm2.btnConnectClick(Sender: TObject);
begin
  IdTCPClient.Host := 'localhost';
  IdTCPClient.Port := 666;
  IdTCPClient.ConnectTimeout := 5000;
  try
    IdTCPClient.Connect;

    Caption := 'Client - Online!';
  except
    Raise;
  end;

end;

procedure TForm2.btnDisconnectClick(Sender: TObject);
begin
  if IdTCPClient.Connected then IdTCPClient.Disconnect;
end;

procedure TForm2.btnSendClick(Sender: TObject);
begin
  if IdTCPClient.Connected then begin
    IdTCPClient.IOHandler.WriteLn(edtCommand.Text);
  end;{if}
end;

procedure TForm2.FormCreate(Sender: TObject);
begin
  Caption := 'Client - Offline';
end;

end.

Jetzt zu den Grundsätzlichen Fragen, ich habe schon das Forum durchstöbert aber irgendwie bin ich noch nicht auf die richtigen
Einträge (Tutorial) gestoßen bzw. ich kapier das irgendwie noch nicht so ganz alles.

Was soll das Ganze, der Server soll wissen welche Clients Angemeldet sind um ggf. ohne Aufforderung des Clients Nachrichten
an einen oder mehre Clients zuschicken, dazu muß er wissen welcher Client wie verbunden ist. Ich habe irgendwelche Ansätze
gefunden die auf "TIdContext" basieren so ganz verstehen tu ich das noch nicht.

Frage 1: Die Verwaltung von mehren Clients an einem Server.


Das nächste Thema ist die Kommunikation zwischen Client und Server, auch zu dem Thema habe ich einiges gefunden. Das man sich
ein "Protokoll" ausdenken sollte nach welchem sich die Anwendungen "unterhalten". Was ja bei einer einfachen Anwendung wie z.B.
einem Chat sicherlich nicht das Problem sein sollte. Da ich jedoch plane dem Server eine Verbindung zu einer mySQL Datenbank
zuverpassen meine Frage macht es da noch sinn alles per "String" zu regeln.
Man könnte vom Client den Befehl schicken "Zeige mir alle Kunden" darauf hin, erstellt der Server eine SQL Abfrage und schickt
dann ja was, einen riesigen zusammenhängenden String zurück, den der Client mühselig wieder in ein Array umsetzten muß um diesen
anzeigen zu können.

Oder kann man irgendwie ein Object bzw. Record übertragen, was macht an der Stelle sinn. Ich hatte irgendwo gelesen man solle
keine Records schicken. Ich frage mich nur was mache ich wenn ich eine Tabelle mit z.B. 10 Spalten und 5000 Zeilen schicken
will die der Client darstellen soll. Das kann man doch wohl kaum alles in einem String machen oder etwas doch.

Was ich mir vorstelle ist eine flexible art der Kommunikation mit einem Protokoll, wo am Anfang jeder Nachricht zum Server
erst mal ein paar Informationen wie z.b. Identität des Clients, der Befehl, evtl. Parameter und falls nötig Daten gesendet werden.

Message vom Client zum Server:
Zitat:
ID: Client_1
CMD: Get_Customer
PARAM: Name
Data:
Daran weiß der Server er muß die Liste der Kunden nach "Name" sortieren und das Ergebnis an den Client schicken, worum es mir
geht ist eine flexible Kommunikation. Sprich der Server empfängt die Nachricht und entscheidet anhand des Befehls (Protokoll)
was zu tun ist, muß jedoch nicht zwischen zig. möglichkeiten der Interpretation der Nachricht welchseln.

Frage 2: Kommunikation zwischen Clients und Server.


Anhand meiner bisherigen Versuche weiß ich zwar das z.B. OnExecute auf der Serverseite für die Auswertung der Nachrichten der
Clients ist, aber wie man da jetzt ansetzt ein Protokoll zu etablieren welches auf Datenstrukturen und nicht auf "simplen" Strings
besteht weiß ich nicht. Und wie ich eine Liste der zur Zeit angemeldenten Clients bekomme und ich dann Nachrichten an diese
Clients geschickt bekomme.

Ich bin über jeden Tipp und vorallem Beispiele dankbar oder wenn jemand entsprechende Tutoriale kennt.

Ansonsten noch einen schönen Tag.

mfg

TUX
  Mit Zitat antworten Zitat
shmia

Registriert seit: 2. Mär 2004
5.508 Beiträge
 
Delphi 5 Professional
 
#2

Re: Grundsatz Fragen Client/Server Anw. via Indy10

  Alt 23. Apr 2009, 14:42
Wie du ganz richtig erkannt hast ist das Protokoll zwischen Client und Server der eigentliche Knackpunkt.
Der Datentransport über TCP/IP (oder Named Pipes, ser. Schnittstelle,...) ist da eigentlich eher nebensächlich.

Es gibt nun verschiedene Arten wie man diese Protokolle aufziehen kann.
Eine einfache Art wäre z.B. ein zeilenbasiertes Befehl- und Antwort Protokoll.
Ein gutes Beispiel dafür ist SMTP, POP3 oder FTP.
Der Client schickt eine Textzeile (abgeschlossen mit CR-LF) als Befehl und der Server antwortet mit einem Status.
Sehr viele Internetprotokolle sind so aufgebaut.

Vorteile: einfach, kann mit einer Teminalemulation von Hand gut getestet werden
Nachteil: schlecht erweiterbar, unflexibel, nicht für komplexe Daten geeignet

Dann gibt es Protokolle, bei denen XML als Grundlage benützt wird.
Alle Daten und Befehle werden als XML verpackt und verschickt.
z.B. XMPP und darauf aufbauend Jabber.

Vorteile: beliebig erweiterbar, für komplexe, hierarchische Daten geeignet
Nachteile: aufwändig, benötigt hohe Netzbandbreite (ca. 95% der Daten sind "Luft")
man kann die XML-Daten vor dem Senden auch komprimieren (zip) und damit den Netzbandbreite reduzieren

Eine sehr interessante Variante zu XML ist JSON.
Mit JSON kann man auch hierarchische Daten aufbauen ohne so weitscheifend wie XML zu sein.

Dann gäbe es noch das SDXF: Structured Data eXchange Format
mit dem man Daten binär und kompakt übertragen kann.
Der Nachteil von binären Protokollen ist aber, dass man nicht so einfach Debuggen kann.

PS:
das Schlechteste, was man tun kann ist binäre Records zu übertragen.
Das ist zwar schnell programmiert, aber sehr unflexibel und schlecht zu portieren.
Verschiedene Programmversionen von Client und Server sind nach Änderungen an den Records nicht mehr kompatibel.
Ein gravierender Nachteil dabei ist auch, dass man Client und Server gleichzeitig entwickeln muss.
Bei allen textbasierten Protokollen kann man zuerst mit dem Server beginnen.
Der Server kann auch leicht mit einem Terminalprogramm getestet werden.
Andreas
  Mit Zitat antworten Zitat
TUX_der_Pinguin

Registriert seit: 1. Jun 2005
Ort: Anholt (NRW)
608 Beiträge
 
Delphi 11 Alexandria
 
#3

Re: Grundsatz Fragen Client/Server Anw. via Indy10

  Alt 23. Apr 2009, 14:54
Hmmm naja also Probleme mit der Bandbreite sollte es keine geben da es sich um eine reine LAN Anwendung handelt mit
vielleicht 10-20 Clients wobei sicherlich höchstens mal 5 oder 10 Clients gleichzeitig online sind.

Die vorteile die für ein Zeilenbasierte Befehl-Antwort Protkoll sprechen sind natürlich nich von der Hand zuweisen.

An XML hatte ich dabei noch gar nicht gedacht, da stellt sich natürlich direkt die Frage wie setzt man das ganze um und
ist es so perfomant das selbst Tabellen mit mehren Hundert Zeilen noch flüssig übertragen und angezeigt werden können das
der Anwender keine oder kaum Verzögerungen spürt. Das ganze kommt auf einen Versuch drauf an.
  Mit Zitat antworten Zitat
shmia

Registriert seit: 2. Mär 2004
5.508 Beiträge
 
Delphi 5 Professional
 
#4

Re: Grundsatz Fragen Client/Server Anw. via Indy10

  Alt 23. Apr 2009, 18:29
Es wäre gut, wenn du die Enterpriseversion von Delphi hättest.
Dort ist die Klasse TClientDataset dabei.
TClientDataset kann ihren Dateninhalt (Felder inkl. Definition + alle Records) als XML laden und speichern.
Andreas
  Mit Zitat antworten Zitat
mjustin

Registriert seit: 14. Apr 2008
3.004 Beiträge
 
Delphi 2009 Professional
 
#5

Re: Grundsatz Fragen Client/Server Anw. via Indy10

  Alt 23. Apr 2009, 19:17
Zitat von shmia:
Es wäre gut, wenn du die Enterpriseversion von Delphi hättest.
Dort ist die Klasse TClientDataset dabei.
TClientDataSet ist eigentlich bei jeder Delphi Version dabei. Nur die Möglichkeit, DataSnap-Clients und Server zu nutzen, ist nicht in der Professional-Versionen enthalten.
Michael Justin
habarisoft.com
  Mit Zitat antworten Zitat
TUX_der_Pinguin

Registriert seit: 1. Jun 2005
Ort: Anholt (NRW)
608 Beiträge
 
Delphi 11 Alexandria
 
#6

Re: Grundsatz Fragen Client/Server Anw. via Indy10

  Alt 24. Apr 2009, 08:49
Naja ich hab nicht die Enterprise Version zur Verfügung, daher finde ich den XML Ansatz noch am interessantesten.

Jetzt ist nur die Frage bastel ich mir da selbst was, erzeuge ich immer ein XML Dokument welches ich einfach via
Writeln() und Readln() hin und herschicke. Oder kann ich da was fertiges nehmen, so ganz kapieren was dieses XMPP
sein soll tu ich noch nicht.


Was neben dem Protokoll bzw. der Kommunikation zwischen Client und Server noch wichtig ist, die Verwaltung der
Clients auf der Server Seite. Ich hab immer noch nicht raus wie ich auf dem Server eine Liste der zur zeit
"angemeldeten" Clients erhalte inkl. möglichkeit diesen auch etwas zuschicken.
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 09:22 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