Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Netzwerke (https://www.delphipraxis.net/14-netzwerke/)
-   -   Client-Server-Datenübertragung (https://www.delphipraxis.net/171938-client-server-datenuebertragung.html)

HJay 3. Dez 2012 16:19

Client-Server-Datenübertragung
 
Ich würde gerne etwa 100-500 KB große Binärdaten innerhalb eines LAN von einem Server an einen Client übertragen.

Da ich so etwas noch nie gemacht habe und es in Delphi 2010 soviele Möglichkeiten gibt (Sockets über API, WinSockets, TTCPClient/Server, Indy, ...), würde ich Euch gerne fragen, was Ihr empfehlen würdet.

Optimal wäre es,

(1) wenn man Streams übertragen könnte (etwa aus serverseitigen TMemoryStream an einen clientseitigen TMemoryStream) oder anderweitig größere Datenmengen in einem Rutsch übertragen könnte;

(2) der Programmieraufwand dabei übersichtlich und geradlinig wäre, also bequem zu benutzen.

Welche Komponenten sind am vorteilhaftesten? Hat jemand ein Beispiel zur Hand?

Vielen Dank im voraus!

Klaus01 3. Dez 2012 16:24

AW: Client-Server-Datenübertragung
 
.. wenn Du Indy verwenden willst.

Stahli hat dazu ein Tutorial verfasst.

Grüße
Klaus

Neumann 3. Dez 2012 16:33

AW: Client-Server-Datenübertragung
 
Die allereinfachste ist, eine gemeinsam erreichbare Freigabe einzurichten. Der Server speichert dort die Daten und der Client holt sie sich.

Methode 2 ist etwas aufwendiger; der Server schickt die Daten per Mail an den Client als Mailattachment. Dafür muss man in beide Programme die Mailfuktion einbauen, etwa mit Indy. Soll das ganze nur intern laufen, braucht man noch einen Mailserver, z.B. HMailer.

Über eine TCP-Verbindung geht es auch; die Verbindung geht dann aber nur wenn beide aktiv sind, Server und Client.

HJay 3. Dez 2012 16:39

AW: Client-Server-Datenübertragung
 
@Neumann: Die Datenübertragung wird oft nötig und ich will gerade auf Schreiben/Lesen in Datenbank oder Filesystem verzichten. Es soll schon direkt per Intranet von Rechner an Rechner übertragen werden. Der Server wird immer laufen, die (vielen) Clients holen sich die Daten immer dann ab, wenn sie sie gerade benötigen.

mjustin 3. Dez 2012 16:40

AW: Client-Server-Datenübertragung
 
Zitat:

Zitat von HJay (Beitrag 1194133)
Ich würde gerne etwa 100-500 KB große Binärdaten innerhalb eines LAN von einem Server an einen Client übertragen.

Mit Indy (TIdTCPServer) ist das einfach zu realisieren. Der Server wartet auf eine Clientverbindung, und sobald sie hergestellt ist, führt er in einer Schleife den "OnExecute" Eventhandler aus.

Wenn eine Datei zur Übertragung bereit ist, sendet der Server sie als Stream mit

Delphi-Quellcode:
// write stream size and then stream data
AContext.Connection.IOHandler.Write(AStream, 0, True);
und der Client liest den Stream mit

Delphi-Quellcode:
// reads the stream size then reads the stream data
Client.IOHandler.ReadStream(MyStream, -1, False);
(wobei der Client ebenfalls in einer Endlosschleife prüft, ob Daten vom Server angekommen sind:


Delphi-Quellcode:
  while not Terminated do
  begin
    IdTCPClient1.IOHandler.CheckForDataOnSource(50);
    if not IdTCPClient1.IOHandler.InputBufferIsEmpty then
    begin
      // Stream - Objekt erzeugen
      ...
      // Daten empfangen
      Client.IOHandler.ReadStream(MyStream, -1, False);
      // Daten verarbeiten und danach Stream freigeben
      ...
    end;
  end;

himitsu 3. Dez 2012 16:42

AW: Client-Server-Datenübertragung
 
Du kannst dir auch DataSnap ansehn.
Dürfte in D2010 Ent. schon drinnen sein.

Hier im Forum suchenDataSnap Bei Google suchenDataSnap



INDY ist aber leichtgewichtiger und, wenn es nur um Streams geht, vollkommen ausreichend.

HJay 3. Dez 2012 16:45

AW: Client-Server-Datenübertragung
 
@mjustin: Kann man sich die Endlosschleifen irgendwie ersparen und das ganze Event- oder Message-basiert ablaufen lassen?

Sowohl Client als auch Server haben auch genug anders zu tun. Meine Anwendung: Der Server rechnet komplexe Daten aus, die Clients rufen sie ab und stellen sie auf verschiedene Arten interaktiv dar.

Hat Indy Vorteile gegenüber TTCPClient/Server?

mjustin 3. Dez 2012 16:49

AW: Client-Server-Datenübertragung
 
Zitat:

Zitat von HJay (Beitrag 1194147)
@Neumann: Die Datenübertragung wird oft nötig und ich will gerade auf Schreiben/Lesen in Datenbank oder Filesystem verzichten. Es soll schon direkt per Intranet von Rechner an Rechner übertragen werden. Der Server wird immer laufen, die (vielen) Clients holen sich die Daten immer dann ab, wenn sie sie gerade benötigen.

In diesem Fall (Client verbindet sich mit Server und fordert Datei an) ist HTTP mit Indy eine einfache Option:

Indy enthält eine HTTP Server Komponente (TIdHTTPServer), der Server liest auf Anforderung des Clients die Datei in einen Stream und überträgt sie an eine TIdHTTP Client Komponente). Welche Datei der Client erhält, entscheidet dabei nur der Server.

mjustin 3. Dez 2012 17:20

AW: Client-Server-Datenübertragung
 
Zitat:

Zitat von HJay (Beitrag 1194151)
@mjustin: Kann man sich die Endlosschleifen irgendwie ersparen und das ganze Event- oder Message-basiert ablaufen lassen?

TCP ist streamorientiert, man erfährt nur dann von der Existenz neuer Daten, wenn man eine Leseoperation auf dem Socket ausführt. Die asynchrone TClientSocket Komponente ist zwar "eventorientiert" in der Anwendung, aber intern nutzt sie die Windows Messageloop und prüft in ihr den Socket.

Wenn der Client aber die Kommunikation mit einem Request startet und der Server dann eine Response zurücksendet, braucht man diese Loop nicht. Ich hatte aufgrund der ersten Beschreibung ("von einem Server an einen Client übertragen") angenommen, dass der Server die Dateiübertragung startet, wenn eine Datei zu senden ist. Das wäre der Fall aus meinem Beispielcode.

Für Request/Response ist HTTP mit Indy passend, der Client muss keine Schleife verwenden um den Socket zu überwachen, sondern nur IdHTTP.Get ausführen, das dann die Daten zurückliefert.

Zitat:

Zitat von HJay (Beitrag 1194151)

Sowohl Client als auch Server haben auch genug anders zu tun.

Ein Thread, in dem der Socket in größeren Zeitabständen mittels z.B. CheckForDataOnSource(50) geprüft wird, belastet das System nicht spürbar.

Zitat:

Zitat von HJay (Beitrag 1194151)

Hat Indy Vorteile gegenüber TTCPClient/Server?

Remy Lebeau schrieb zu den TTcpServer/TTcpClient Komponenten:

Zitat:

They are also very poorly implemented, and not very useful, IMHO. They are
not VCL components to begin with, they are CLX components from the Kylix
days. Borland tried to write its own cross-platform socket components, but
narrowed everything down to a VERY bare-bones least-common-denominator
implementation between Windows and Linux that requires ALOT of manual work
in user code. As such, you are better off either re-installing the old VCL
sockets components, or switch to Indy's TIdTCPClient and TIdTCPServer
components (Indy has been bundled with Delphi since D6) or other third-party
library (like ICS or Synapse).

HJay 3. Dez 2012 17:39

AW: Client-Server-Datenübertragung
 
Zitat:

Zitat von himitsu (Beitrag 1194150)
Du kannst dir auch DataSnap ansehn.
Dürfte in D2010 Ent. schon drinnen sein.

DataSnap kenne ich noch gar nicht, aber auf den ersten Blick klingt das richtig genial.

Wenn ich das auf die Schnelle auf den Embarcadero-Seiten richtig verstanden habe, dann können sich Server und Client ganze selbstdefinierte Delphi-Objekte TMyClass() einschließlich aller Daten-Inhalte und Methoden teilen und der Client auf die Server-Daten einfach so zugreifen? Und das geht auch mit eigenen komplexen, abgeleiteten Objekten?

Man muss sich dann gar nicht um Synchronisation und dergleichen kümmern? Das wäre genial! Es geht bei mir nämlich in der Tat um die Zuverfügungstellung großer Objekte, die ich sonst extra als komprimierte XML versucht hätte zu übertragen.

Kann man dem Client auch ein Event-Signal geben, wann es wieder auf die Server-Daten zugreifen soll, z.B. wenn Veränderungen stattgefunden haben?

Darf der Server an seinen Daten jederzeit etwas ändern, ohne dass man sich um die Synchronisation Gedanken machen muss? Kann man für die Dauer des "Neuaufbaus" oder der Rechnung die Daten blockieren oder geschieht das automatisch, wenn der Server halt in einer Routine drin streckt?

Hm, klingt erst einmal gut, wäre viel Einarbeitung, aber vielleicht richtig lohnend.

HJay 3. Dez 2012 17:42

AW: Client-Server-Datenübertragung
 
@mjustin: Danke, idHTTP werde ich mir morgen früh mal anschauen.

Die DataSnap-Idee werde ich morgen auch weiterverfolgen und vielleicht mal mit einem kurzen Demoprojekt ausprobieren.

stahli 3. Dez 2012 18:35

AW: Client-Server-Datenübertragung
 
DataSnap ist für solche Dinge gedacht.
Man kann Datasets, Streams und Objekte übertragen und auch Methoden vom Client aus auf dem Server ausführen.

Allerdings ist das Framework ziemlich fett und (was man so hört) relativ langsam und u.U. fehleranfällig.

Aber versuchen würde ich es an Deiner Stelle...


Bei den Indys muss immer der Client beim Server anfragen, der dann "nix" oder "ObjektDaten" zurück schickt.
Prinzipiell sollte das auch machbar sein.

mjustin 3. Dez 2012 19:32

AW: Client-Server-Datenübertragung
 
Zitat:

Zitat von stahli (Beitrag 1194173)
Bei den Indys muss immer der Client beim Server anfragen, der dann "nix" oder "ObjektDaten" zurück schickt.

So ist es eigentlich nicht: bei jeder TCP Verbindung sind beide Seiten völlig gleichberechtigt, der "Server" kann auch von sich aus das Senden von Daten an den "Client" beginnen. Bekannte asynchrone und bidirektionale Protokolle sind Telnet, WebSocket und STOMP.

stahli 3. Dez 2012 20:38

AW: Client-Server-Datenübertragung
 
@mjustin
Bist Du sicher? Hast Du mal einen Link zu einem Beispiel?

Bummi 3. Dez 2012 22:09

AW: Client-Server-Datenübertragung
 
@stahli
das ist einer der Gründe warum ich für einfache Komponenten wie TCPClient unf TCPServer plädiert habe. Man merkt dann schneller dass da einfach eine nur Verbindung offen ist und kann sich in beider Richtungen austoben.

mjustin 4. Dez 2012 08:53

AW: Client-Server-Datenübertragung
 
Zitat:

Zitat von stahli (Beitrag 1194193)
@mjustin
Bist Du sicher? Hast Du mal einen Link zu einem Beispiel?

Gerne, auf Stackoverflow zum Beispiel hier:

Indy TCP Client/Server with the client acting as a server

Delphi-Quellcode:
var
  sPrompt: String;
  sResponse: String;
begin
  // Set port to connect to
  IdTCPClient1.Port := 8080;
  // Set host to connect to
  IdTCPClient1.Host := '127.0.0.1';
  // Now actually connect
  IdTCPClient1.Connect;
  // Read the prompt text from the server
  sPrompt := IdTCPClient1.Socket.ReadLn;
  // Show it to the user and ask the user to respond
  sResponse := InputBox('Prompt', sPrompt, '');
  // Send user's response back to server
  IdTCPClient1.Socket.WriteLn(sResponse);
  // Show the user the server's final message
  ShowMessage(IdTCPClient1.Socket.AllData);
end;
oder serverseitig:

Delphi-Quellcode:
var
  sName: String;
begin
  // Send command to client immediately after connection
  AContext.Connection.Socket.WriteLn('What is your name?');
  // Receive response from client
  sName := AContext.Connection.Socket.ReadLn;
  // Send a response to the client
  AContext.Connection.Socket.WriteLn('Hello, ' + sName + '.');
  AContext.Connection.Socket.WriteLn('Would you like to play a game?');
  // We're done with our session
  AContext.Connection.Disconnect;
end;

Klaus01 4. Dez 2012 09:03

AW: Client-Server-Datenübertragung
 
.. das liegt doch schon im Protokoll (TCP) begründet, dass wenn eine Verbindung etabliert ist der Server auch mit dem Client kommunizieren kann.

Einzig der Client ist in der Lage ein TCP Verbindung zu initiieren.

Grüße
Klaus

mjustin 4. Dez 2012 09:28

AW: Client-Server-Datenübertragung
 
Zitat:

Zitat von Klaus01 (Beitrag 1194224)
Einzig der Client ist in der Lage ein TCP Verbindung zu initiieren.

Ein Computer kann ein Server und Client zugleich sein (http://de.wikipedia.org/wiki/Client-Server-Modell).

Client ist die Seite, die einen Dienst auf einem Server nutzt. In der Regel stellt er auch die Verbindung her.

Eine bekannte Ausnahme von dieser Regel ist FTP im Active Modus, hierbei meldet sich der FTP Client an, danach baut der FTP Server eine Verbindung zum Client auf.

Bei Peer-To-Peer Netzen, in denen jeder Computer Verbindungen sowohl initiiert als auch akzeptiert, sind alle Rechner Client und Server gleichzeitig.

HJay 5. Dez 2012 11:31

AW: Client-Server-Datenübertragung
 
Kurzes Feedback von mir:

DataSnap habe ich mit Delphi 2010 nicht zum Laufen bekommen. Alle Embarcadero-Tutorials setzen höhere Versionen voraus. Das in den Tutorial notwendige "DataSnap-Client-Module" gibt es bei mir unter "Menu > Neu > DataSnap" gar nicht. Schade, wäre einen Versuch wert gewesen. -- Zum Glück plane ich aber ohnehin ein Upgrade auf XE3 und werde mir die Sache dann noch einmal ansehen.

Also werde ich die kommenden Tage noch einmal einen Blick auf die vorgeschlagenen Indy-Komponenten werfen. Das war ja wohl die Empfehlung hier, oder? Bezüglich Internet gibt es dermaßen viel Auwahl, dass es wirklich schwer ist, sich als Anfänger zu entscheiden. Da hätte ich mir eher EINEN Satz perfekter, ausgereifter Komponenten gewünscht statt so ein Wirrwarr.

Danke für Eure Antworten in diesem Thread!

Sir Rufo 5. Dez 2012 11:37

AW: Client-Server-Datenübertragung
 
Als Alternative gibt es auch noch mORMot

HJay 20. Dez 2012 21:45

AW: Client-Server-Datenübertragung
 
@mjustin: Ich habe eben Dein "Web Framework" entdeckt. Meinst Du, dies wäre für mich eine praktikable Lösung? Immerhin sieht das ganze recht einfach zum Benutzen aus.

Könnten sich dort z.B. ein Dutzend Clients gleichzeitig und regelmäßig per HTTP Daten abholen, die ZIP, JPG, ASCII oder sonstwas sein können? Kriegt man das leicht hin? Kann man BINÄREN Response-Content aus einem Stream erstellen und übertragen?

mjustin 21. Dez 2012 12:26

AW: Client-Server-Datenübertragung
 
Zitat:

Zitat von HJay (Beitrag 1196334)
@mjustin: Ich habe eben Dein "Web Framework" entdeckt. Meinst Du, dies wäre für mich eine praktikable Lösung? Immerhin sieht das ganze recht einfach zum Benutzen aus.

Könnten sich dort z.B. ein Dutzend Clients gleichzeitig und regelmäßig per HTTP Daten abholen, die ZIP, JPG, ASCII oder sonstwas sein können? Kriegt man das leicht hin? Kann man BINÄREN Response-Content aus einem Stream erstellen und übertragen?

Ja, im Prinzip geht das alles. Ich kann voraussichtlich erst später oder am Wochenende ausführlicher antworten. Vielen Dank für das Interesse!

HJay 21. Dez 2012 15:35

AW: Client-Server-Datenübertragung
 
@mjustin: Keine Eile! Jetzt kommt auch bei mir erst einmal Weihnachten. Ab dem "dritten Weihnachtstag" bin ich wieder am Rechner und würde mich dafür interessieren.

Für mich sieht es so aus:

Es ist ein mächtiges, großes Projekt und letztlich möchte ich nur statt wie bisher über das Datenbank- oder Filesystem direkt per Intranet Daten zwischen einem Server (zieht Daten aus vielen Quellen und rechnet kräftig herum) und Clients (zeigen die errechneten Daten auf vielen Endnutzer-Rechnern in verschiedenen Formen an) austauschen.

Für mich haben daher hier zwei Dinge Vorrang:
+ Bequemlichkeit bei der Implementierung
+ Stabilität

Ich bin etwas hin- und hergerissen zwischen der Perspektive, es einfach selbst mit Indy HTTP zu probieren oder eben Dein Web Framework einzusetzen. Einfach, stabil, problemlos wäre klasse...

taveuni 21. Dez 2012 15:55

AW: Client-Server-Datenübertragung
 
Oder trifft alles auf RemObjects zu.

sh17 21. Dez 2012 16:20

AW: Client-Server-Datenübertragung
 
Mit NexusDB kann man per Plugin Remote FileStreams lesen und schreiben

http://www.nexusdb.com/support/index.php?q=node/10167


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