AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Netzwerke Delphi Beispielcode für TCP Socket Client Bibliotheken (Delphi & Free Pascal)

Beispielcode für TCP Socket Client Bibliotheken (Delphi & Free Pascal)

Ein Thema von mjustin · begonnen am 11. Dez 2022 · letzter Beitrag vom 13. Dez 2022
Antwort Antwort
mjustin

Registriert seit: 14. Apr 2008
3.006 Beiträge
 
Delphi 2009 Professional
 
#1

Beispielcode für TCP Socket Client Bibliotheken (Delphi & Free Pascal)

  Alt 11. Dez 2022, 14:22
Für meine Delphi- und Free Pascal Projekte verwende ich diverse TCP Bibliotheken.

Diese unterscheiden sich in ihrer API, manche sind eher high-level orientiert, andere nur ein kleiner Wrapper für die Windows API.
Das macht einen Wechsel, oder bibliotheksunabhängige Programmierung (bei der mehrere Bibliotheken unterstützt werden) nicht leicht.
Dadurch motiviert, sammele ich auf GitHub nun Codebeispiele für typische, einfache, Aufgabenstellungen.

Die Repository-Adresse ist https://github.com/michaelJustin/tcpclient-test

Teil 1: Lesen einer festen Anzahl von Bytes
Im ersten Teil des Projekts geht es um das Lesen einer festen Anzahl von Bytes vom Server. Dazu gibt es einen TCP Server, der dem Client eine feste Anzahl bytes zurückgibt und dann die Verbindung trennt.

Client-Testanwendungen für diese Bibliotheken sind enthalten:
* Indy 10 - https://github.com/IndySockets/Indy
* Ararat Synapse - https://sourceforge.net/p/synalist/c...AD/tree/trunk/
* Synopse - https://synopse.info

Alle Client-Beispiele enthalten nur eine Methode:

function Read(AHost: string; APort: Integer; ALength: Integer): TBytes; Diese wird von der Test-Methode aufgerufen, und die zurückggebene Länge ermittelt und ausgegeben.

Für Indy sieht das Beispiel folgendermassen aus:
Delphi-Quellcode:
program FixedLengthClient;

uses
  ClientMainIndy10,
  SysUtils;

const
  CONTENT_LENGTH = 8192;
  SERVER_HOST = '127.0.0.1';
  SERVER_PORT = 30000;

  procedure Test(AExpectedLength: Integer);
  var
    Response: TBytes;
  begin
    WriteLn(Format('try to read %d bytes from %s:%d',
      [AExpectedLength, SERVER_HOST, SERVER_PORT]));
    Response := Read(SERVER_HOST, SERVER_PORT, AExpectedLength);
    WriteLn(Format('received %d bytes', [Length(Response)]));
  end;

begin
  try
    Test(CONTENT_LENGTH);
    Test(CONTENT_LENGTH - 1);
    Test(CONTENT_LENGTH + 1); // (surprise me)
  except
    on E: Exception do
    begin
      WriteLn(E.Message);
    end;
  end;
  ReadLn;
end.
Für jede Bibliothek muss nur die entsprechende Unit verwendet werden, und die anderen auskommentiert:
Delphi-Quellcode:
uses
  //ClientMainIndy10,
  //ClientSynapse266,
  ClientSynopseCrtSock,
  SysUtils;
Die Projekte sind zwar mit Free Pascal / Lazarus erstellt, sollten aber mit Delphi 2009 und neuer kompatibel sein. (Delphi dpr Dateien können durch Umbenennen der lpr erzeugt werden)
Michael Justin
habarisoft.com

Geändert von mjustin (11. Dez 2022 um 18:38 Uhr) Grund: Tag "Sockets" fehlte
  Mit Zitat antworten Zitat
Benutzerbild von jaenicke
jaenicke

Registriert seit: 10. Jun 2003
Ort: Berlin
9.580 Beiträge
 
Delphi 11 Alexandria
 
#2

AW: Beispielcode für TCP Client Bibliotheken (Delphi & Free Pascal)

  Alt 11. Dez 2022, 14:54
Tatsächlich habe ich beruflich gerade ein ähnliches Thema bearbeitet (HTTP und Rest statt TCP). Ich habe eine Wrapperklasse erstellt, der man einfach sagen kann, welches Framework sie zur Kommunikation nutzen soll und ob die Kommunikation asynchron erfolgen soll. Diese asynchrone Kommunikation finde ich, gerade bei solchen Beispielen, sehr wichtig, denn diese ist noch schwieriger unter einen Hut zu bekommen.

Statt mehrere einzelne Beispiele zu schreiben, wäre vielleicht eine Überlegung, auch hier einen Wrapper zu schreiben, den man dann frameworkunabhängig nutzen kann.

Ich würde in die Liste der Framworks noch ICS aufnehmen. Das gefällt mir sehr gut, unter anderem weil z.B. bei (ja, anderes Thema) SSL-Verbindungen sehr ausführliche und hilfreiche Logs geschrieben werden können und auch die (im Gegensatz zu Indy) non-blocking sockets finde ich sehr nützlich.
Sebastian Jänicke
Alle eigenen Projekte sind eingestellt, ebenso meine Homepage, Downloadlinks usw. im Forum bleiben aktiv!
  Mit Zitat antworten Zitat
mytbo

Registriert seit: 8. Jan 2007
472 Beiträge
 
#3

AW: Beispielcode für TCP Socket Client Bibliotheken (Delphi & Free Pascal)

  Alt 11. Dez 2022, 20:02
Das macht einen Wechsel, oder bibliotheksunabhängige Programmierung (bei der mehrere Bibliotheken unterstützt werden) nicht leicht.
Nur aus Neugierde, warum möchtest du mehrere Bibliotheken unterstützen? Synopse mORMot, ich würde dir mORMot2 empfehlen, unterstützt Delphi ab Version 7 und FPC. Die Klasse TCrtSocket ist beschrieben mit: "Fast low-level Socket implementation, direct access to the OS (Windows, Linux) network layer API, ...our classes are (much) faster than the Indy or Synapse implementation". Für die asynchrone Kommunikation gibt es die Klassen TAsyncServer/TAsyncClient.

Bis bald...
Thomas
  Mit Zitat antworten Zitat
Benutzerbild von Codehunter
Codehunter

Registriert seit: 3. Jun 2003
Ort: Thüringen
2.272 Beiträge
 
Delphi 10.4 Sydney
 
#4

AW: Beispielcode für TCP Socket Client Bibliotheken (Delphi & Free Pascal)

  Alt 13. Dez 2022, 10:04
Das ist irgendwie eine ähnliche Diskussion wie "Was ist besser: Windows oder [xyz]?" Letztlich muss man sich selbst fragen: Wie wichtig ist einem das Thema Netzwerkkommunikation im eigenen Projekt? Wie viel Arbeit will ich investieren? Soll das Projekt plattformunabhängig sein? Vertraue ich einem bestimmten Hersteller und/oder proprietären OS?

Ich persönlich nutze Indy, weil es plattformunabhängig ist und ziemlich Low-Level ansetzt um den gesamten Protokollstack selbst abzubilden. Leider ist die Entwicklung in den letzten Jahren ins Stocken geraten, vor allem weil Remy kaum noch Zeit dafür hat. So ist z.B. OpenSSL 1.1 immer noch nicht final im Hauptzweig integriert. Dabei war OpenSSL genau der Grund, weshalb ich mich damals nicht auf die Emba-Lösung eingelassen habe, denn die setzt unter Windows auf WinInet und da ist man bei SSL/TLS-Verbindungen auf Gedeih und Verderb deren Zertifikatspeicher ausgeliefert - und den hat Microsoft schon mehrfach per Windowsupdate sabotiert. Bisher bin ich mit Indy sehr gut gefahren, noch gibt es keine TLS-1.3-only-Server in meinem Ökosystem, aber irgendwann wirds passieren und dann wären wir mit Indy und OpenSSL 1.0.x angeschmiert.
Ich mache grundsätzlich keine Screenshots. Schießen auf Bildschirme gibt nämlich hässliche Pixelfehler und schadet der Gesundheit vom Kollegen gegenüber. I und E zu vertauschen hätte den selben negativen Effekt, würde aber eher dem Betriebsklima schaden
  Mit Zitat antworten Zitat
Benutzerbild von jaenicke
jaenicke

Registriert seit: 10. Jun 2003
Ort: Berlin
9.580 Beiträge
 
Delphi 11 Alexandria
 
#5

AW: Beispielcode für TCP Socket Client Bibliotheken (Delphi & Free Pascal)

  Alt 13. Dez 2022, 10:36
denn die setzt unter Windows auf WinInet und da ist man bei SSL/TLS-Verbindungen auf Gedeih und Verderb deren Zertifikatspeicher ausgeliefert - und den hat Microsoft schon mehrfach per Windowsupdate sabotiert.
Das stimmt nicht. Ich verwende die delphieigenen Klassen für Rest und Http und nutze Zertifikate aus Dateien. In Delphi 11.2 funktioniert das nun auch direkt ohne Tricks.

Da neuere Verschlüsselungen oder Kurven nicht unbedingt von allen Frameworks unterstützt werden, ist es gut, wenn man das Framework bei Bedarf relativ einfach wechseln kann.
Sebastian Jänicke
Alle eigenen Projekte sind eingestellt, ebenso meine Homepage, Downloadlinks usw. im Forum bleiben aktiv!
  Mit Zitat antworten Zitat
Benutzerbild von Codehunter
Codehunter

Registriert seit: 3. Jun 2003
Ort: Thüringen
2.272 Beiträge
 
Delphi 10.4 Sydney
 
#6

AW: Beispielcode für TCP Socket Client Bibliotheken (Delphi & Free Pascal)

  Alt 13. Dez 2022, 15:44
denn die setzt unter Windows auf WinInet und da ist man bei SSL/TLS-Verbindungen auf Gedeih und Verderb deren Zertifikatspeicher ausgeliefert - und den hat Microsoft schon mehrfach per Windowsupdate sabotiert.
Das stimmt nicht. Ich verwende die delphieigenen Klassen für Rest und Http und nutze Zertifikate aus Dateien. In Delphi 11.2 funktioniert das nun auch direkt ohne Tricks.

Da neuere Verschlüsselungen oder Kurven nicht unbedingt von allen Frameworks unterstützt werden, ist es gut, wenn man das Framework bei Bedarf relativ einfach wechseln kann.
Das meinte ich nicht. SSL und TLS sind so aufgebaut, dass es (mehr oder weniger) vertrauenswürdige Zertifizierungsstellen gibt,z.B. Letsencrypt oder Symantec. Ein Server im Web liefert seine öffentlichen Schlüssel und der Client prüft dann entlang der Keychain zur Zertifizierungsstelle. Das ist aus gutem Grund so gewollt, wie man an den verschiedenen Skandalen rund um die Zertifizierungsstellen in der Vergangenheit gesehen hat. Dieser Tage wollten Mozilla und Google z.B. die Trustcor-Rootzertifikate sperren.

Die Browser bringen diese Prüfinfrastruktur selbst mit, Microsoft liefert aber mit WinInet auch eine API zu einer solchen Infrastruktur. Die meinte ich, die hat Windows Update schon mehrfach kaputt gepatched. Aus Anwendungssicht ist der Effekt dann der selbe: Du bekommst keine verschlüsselte Verbindung aufgebaut. Also neben der gewollten Sollbruchstelle noch eine ungewollte.
Ich mache grundsätzlich keine Screenshots. Schießen auf Bildschirme gibt nämlich hässliche Pixelfehler und schadet der Gesundheit vom Kollegen gegenüber. I und E zu vertauschen hätte den selben negativen Effekt, würde aber eher dem Betriebsklima schaden
  Mit Zitat antworten Zitat
mjustin

Registriert seit: 14. Apr 2008
3.006 Beiträge
 
Delphi 2009 Professional
 
#7

AW: Beispielcode für TCP Socket Client Bibliotheken (Delphi & Free Pascal)

  Alt 13. Dez 2022, 19:16
Danke für das Feedback und die Anregungen! Ich freue mich natürlich auch über Pull Requests auf das GitHub Repository mit Vorschlägen, alternativ gerne per PM etc.

Nun ist der zweite Teil erschienen:

Teil 2: Lesen eines Snowman ☃ - terminierten Strings von einem TCP Socket

Dazu gibt es auch wieder einen Artikel.

Der Server sendet in diesem Beispiel einen kurzen Text an den Client, gefolgt von der Byte-Sequenz $2603, dies ist der Unicode-Wert für das Snowman Symbol.
Die clientseitige Implementierung für Indy und Synapse ist relativ kompakt und leicht lesbar. Hier die für Synapse:
Delphi-Quellcode:
function ReadDelimited(AHost: string; APort: Integer; ATerminator: RawByteString): string;
var
  FSock: TTCPBlockSocket;
begin
  FSock := TTCPBlockSocket.Create;
  try
    FSock.RaiseExcept := True;
    FSock.Connect(AHost, IntToStr(APort));
    Result := FSock.RecvTerminated(1000, ATerminator);
   finally
     FSock.Free;
   end;
end;
Der Terminator wird dazu im Beispiel als Konstante definiert:
  FIXED_DELIMITER = '' + #$2603; // '☃'; Das Testprogramm sieht aktuell so aus:

Delphi-Quellcode:
program FixedDelimiterClient;

uses
  ClientIndySockets10,
  //ClientSynapse266,
  //ClientSynopseCrtSock,
  SysUtils;

const
  FIXED_DELIMITER = '' + #$2603; // '☃';
  SERVER_HOST = '127.0.0.1';
  SERVER_PORT = 30000;

  procedure Test(ADelimiter: string);
  var
    Response: string;
  begin
    WriteLn(Format('try to read from %s:%d delimited with %s',
      [SERVER_HOST, SERVER_PORT, ADelimiter]));
    Response := ReadDelimited(SERVER_HOST, SERVER_PORT, Utf8Encode(ADelimiter));
    WriteLn(Format('received response "%s" - %d bytes',
      [Response, Length(Response)]));
  end;

begin
  try
    Test(FIXED_DELIMITER);
    Test(FIXED_DELIMITER);
    Test(FIXED_DELIMITER);
  except
    on E: Exception do
    begin
      WriteLn(E.Message);
    end;
  end;
  ReadLn;
end.
Da es eine Konsolenanwendung ist, sieht man den Snowman leider nicht.
Es erscheint nur "try to read from 127.0.0.1:30000 delimited with ?'
Michael Justin
habarisoft.com
  Mit Zitat antworten Zitat
Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

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 23:50 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