kopf
brlogo
fensterobenrechts
   
   
fensteruntenblau
   
   
header
 

bt_backward  bt_index   bt_forward

Erste Kontaktaufnahme (Basisprogramm für die Socket-Programmierung)

 

Dieses erste Programmbeispiel beschreibt die grundlegenden Techniken der Socket-Programmierung unter Verwendung der beiden Delphi-Klassen TServerSocket und TClientSocket.

Client-Server-Anwendungen verwenden in der Regel unterschiedliche Rechner für das Server- und das Client-Programm. Für diesen ersten Zugriff (Programm Kontakt1) verwendet das Programm zugleich einen Serversocket und einen Clientsocket, repräsentiert durch zwei verschiedene Fenster. Man kann damit beide Aspekte der Client-Server Kommunikation in einem Programm  erfahren und ausprobieren.

Das Programm verwendet als IP Adresse die symbolische Adresse 'Localhost' (= 127.0.0.1) und den Port 8181 für den Serversocket.

 

Projektbeschreibung

 

kontakt_10

 

Das Programm Kontakt1 beschreibt und demonstriert die grundlegenden Techniken der Kontaktaufnahme von einem Client mit einem Server und die Kommunikation dieser beiden Sockets. Das Programm enthält neben dem Hauptfenster hierzu zwei weitere Fenster, die als Server- und als Client-Prozess arbeiten. Demzufolge besitzen diese Fenster jeweils eine Serversocket- bzw. eine Clientsocket-Komponente, dazu weitere Steuerelemente.

Sprechweise: Wir sprechen im Weiteren etwas unpräzise, aber vereinfachend von einem Server (bzw. Client), und identifizieren den Server-Rechner mit dem Server-Programm und mit seinem Serversocket.

 

Das Server-Fenster

 

Das Server-Programm enthält eine Schaltfläche um den Serversocket zu starten oder zu stoppen., ferner ein Memo-Feld, um den Status der Kommunikation anzuzeigen, und natürlich eine Serversocket-Komponente.

 

kontakt_20

 

Die Namen der Komponenten:

 

Name
Komponente
FrmServer Formular
ServerSocket Serversocket-Komponente
BtStartStop Schaltfläche
MemStatus Memo-Feld
 

 

Vorbereitungen des Servers

 

Damit sich ein Client mit dem Server verbinden kann, muss dieser vorher

  • einen Socket für die erste Kontaktaufnahme bereitstellen, und
  • diesen Socket öffnen
Port = 8181   Der Port ist hier mit 8181 voreingestellt.
Host = Localhost  oder
Host = 127.0.0.1
Als IP Adresse verwendet eine Serversocket-Komponente die des aktuellen Rechners.
 

Eigenschaft Socket

Socket-Komponenten besitzen die Eigenschaft Socket. Diese existiert nur zur Laufzeit des Programms und wird daher nicht im Objektinspektor angezeigt. Die Eigenschaft Socket kapselt Socket-Objekte, die die Funktionalität eines Sockets aus dem WinSock-API bereitstellen. Daher sind unter dieser Eigenschaft weitere Eigenschaften und Methoden vorhanden, insbesondere die zum Start eines Sockets.

 

Öffnen und Schließen eines  Sockets

 

mittels Methode:
ServerSocket.Open
ServerSocket.Close
oder mittels Eigenschaft:
ServerSocket.Active := True
ServerSocket.Active := False
 

Die Ereignismethode der Schaltfläche BtStartStop, die den Server öffnet oder schließt, demonstriert die Verwendung der oben beschriebenen Eigenschaften und Methoden.

 

procedure TFrmServer.BtStartStopClick (Sender: TObject);
begin
  if ServerSocket.Active
    then begin
      ServerSocket.Active := False;
     
// ServerSocket.Close;
      BtStartStop.Caption := 'Server Start';
      MemStatus.Lines.Add ('Status: Server angehalten')
    end
    else begin
      ServerSocket.Active := True;
      // ServerSocket.Open;
      ServerAktiv := True;
      BtStartStop.Caption := 'Server Stop';
      MemStatus.Lines.Add ('Status: Server gestartet')
    end
end;


Server aktiv?
ja: Server anhalten
geht auch



nein: Server starten
geht auch
 

 

Das Client-Fenster

 

Das Client-Fenster hat die gleiche Struktur wie das Server-Fenster: Mithilfe der Schaltfläche BtVerbinden kann sich der Client mit dem Serversocket verbinden und diese Verbindung wieder trennen. Der Status des Clients wird im Memo-Feld protokolliert.

 

kontakt_30

 

 

Die Fensterkomponente verwendet das Attribut Verbunden: Boolean für die interne Verwaltung des Zustandes der Verbindung.

 

Die Namen der verwendeten Komponenten:

 

Name Komponente
FrmClient   Formular
Verbunden: Boolean; (interne) Zustandsvariable
ClientSocket Clientsocket-Komponente
BtVerbinden Schaltfläche
MemStatus Memo-Feld
 

 

Verbinden mit dem Serversocket

 

Bevor ein Clientsocket aktiviert werden kann, muss er mit der IP Adresse und dem Port des Serversockets initialisiert werden, bei dem er sich anmelden möchte. Initialisiert wird entweder mithilfe des Objektinspektor zur Entwicklungszeit des Programms (siehe oben Grafik) oder zur Laufzeit mittels Wertzuweisung (siehe unten Programmbeispiel). Die Ereignismethode der Schaltfläche BtVerbinden demonstriert das Verbinden des Clients mit einem Server und das Trennen dieser Verbindung.

 

procedure TFrmClient.BtVerbindenClick(Sender: TObject);
begin
   if Verbunden
     then begin
       ClientSocket.Close;
      
Verbunden := False;
       BtVerbinden.Caption := 'Mit Server verbinden';
     end
     else begin
       ClientSocket.Host := Adresse;
       ClientSocket.Port := Port;
       ClientSocket.Open;   
   
      
Verbunden := True;
       BtVerbinden.Caption := 'Vom Server trennen';
     end
end;


Mit Server verbunden?
ja: Verbindung trennen



nein: Verbindung herstellen
 
 

 

Fehlermeldungen

 

Lässt sich eine der oben beschriebenen Socket-Operationen nicht ausführen, tritt also ein Verbindungsfehler auf, so wird für die betroffene Socket-Komponente das Ereignis OnError ausgelöst und das Programm mit einem entsprechenden Error-Code unterbrochen.

Typisches Beispiel:  Der Client versucht sich mit dem nicht geöffneten Server zu verbinden (Fehlermeldung 100061)

kontakt_40

 

 

Man kann diese Programmunterbrechung unterbinden, indem man diese Fehlermeldungen in der zum Ereignis OnError gehörenden Ereignismethode bearbeitet und abschließend den Error-Code auf  0 zurücksetzt. Da diese Ereignismethode vor der Error-Behandlung des Delphi-Systems bearbeitet wird, wird hierdurch ein solcher Programmabbruch verhindert

 

procedure TFrmClient.ClientSocketError (Sender: TObject; Socket: TCustomWinSocket;
                                        ErrorEvent: TErrorEvent; var ErrorCode: Integer);
begin
  MemStatus.Lines.Add ('Status: Fehler ' + IntToStr(ErrorCode));
   ...
  ErrorCode := 0;
end;


Eventuell weitere Reaktionen auf
den Fehler
Verhindert eine Fehlermeldung des Systems
 
 

 

Weitere Ereignisse

 

Auch während der einzelnen Aktionen zwischen Client und Server (Verbinden, Trennen, Datenaustausch) werden Delphi-typisch zahlreiche Ereignisse ausgelöst.

 

Wichtige Ereignisse des Client-Socket-Komponente

 

Ereignis
Das Ereignis tritt ein
OnConnect
unmittelbar vor dem Öffnen der Verbindung zu Serversocket
OnRead
wenn ein Clientsocket Informationen aus der Socketverbindung lesen soll
OnWrite
wenn ein Clientsocket Informationen in die Socketverbindung schreiben soll
OnDisconnect
vor dem Schließen der Verbindung zu einem Servesocket
OnError
wenn ein Socket eine Verbindung nicht erstellen, verwenden oder schließen kann

 

Wichtige Ereignisse des Serversocket-Komponente

 

Ereignis
Das Ereignis tritt ein
OnAccept unmittelbar nach dem Akzeptieren der Verbindung mit einem Clientsocket
OnClientConnect wenn ein Clientsocket eine vom Serversocket akzeptierte Verbindung einrichtet
OnClientRead wenn der Serversocket Informationen aus dem Clientsocket lesen muss
OnClientWrite wenn der Serversocket Informationen in einen Clientsocket schreiben muss
OnClientDisconnect wenn eine der Verbindungen zu einem Clientsocket geschlossen wird
OnClientError wenn beim Einrichten, Verwenden oder Beenden der Socketverbindung zu einem Clientsocket ein Fehler auftritt

 

Beispiel

 

Bei der Aktivierung eines Clientsockets werden die den Ereignisse zugeordneten Ereignis-Methoden in dieser Abfolge ausgeführt:

 

// Zustand: Clientsocket inaktiv
procedure TFrmClient.ClientSocketConnecting (Sender: TObject; Socket: TCustomWinSocket);
begin
  MemStatus.Lines.Add ('Status: Verbindung wird aufgebaut');
end;
procedure TFrmClient.ClientSocketConnect (Sender: TObject; Socket: TCustomWinSocket);
begin
  MemStatus.Lines.Add ('Status: Verbindung hergestellt');
end;

// Zustand: Clientsocket aktiv (mit einem Serversocket verbunden)
// Mögliche Ereignisse:
procedure TFrmClient.ClientSocketRead (Sender: TObject; Socket: TCustomWinSocket);
begin
    ...
end;
procedure TFrmClient.ClientSocketWrite (Sender: TObject; Socket: TCustomWinSocket);
begin
    ...
end;
procedure TFrmClient.ClientSocketError (Sender: TObject; Socket: TCustomWinSocket;
                                         ErrorEvent: TErroeEvent; var ErrorCode: Integer);
begin
  MemStatus.Lines.Add ('Status: Fehler ' + IntToStr(ErrorCode));
  ErrorCode := 0
end;
procedure TFrmClient.ClientSocketDisconnect (Sender: TObject; Socket: TCustomWinSocket);
begin
  MemStatus.Lines.Add ('Status: Verbindung wird getrennt');
end;
// Zustand: Clientsocket inaktiv

 

Analog einige Ereignis-Methoden des Serversockets

 

// Zustand:  Server aktivprocedure TFrmServer.ServerSocketAccept (Sender: TObject; Socket: TCustomWinSocket);
begin
  MemStatus.Lines.Add ('Status: Client verbunden');
  Socket.SendText ('Willkommen, Client ... ')
end;
procedure TFrmServer.ServerSocketClientConnect(Sender: TObject; Socket: TCustomWinSocket);
begin
  MemStatus.Lines.Add ('Status: Client verbunden');
  Socket.SendText ('Willkommen, Client ... ')
end;
procedure TFrmServer.ServerSocketClientRead (Sender: TObject; Socket: TCustomWinSocket);
begin 
  MemStatus.Lines.Add (Socket.ReceiveText);
  Socket.SendText ('Hallo, Peter ...');
end;
procedure TFrmClient.ClientSocketError (Sender: TObject; Socket: TCustomWinSocket;
                                         ErrorEvent: TErroeEvent; var ErrorCode: Integer);
begin
  MemStatus.Lines.Add ('Status: Fehler ' + IntToStr(ErrorCode));
  ErrorCode := 0
end;
procedure TFrmServer.ServerSocketClientDisconnect(Sender: TObject; Socket: TCustomWinSocket);
begin
  MemStatus.Lines.Add ('Status: Client abgemeldet');
  Socket.SendText ('Tschüss, Client ... ')
end;
 

 

Wird das Programm Kontakt1 um diese Ereignis-Methoden ergänzt, ergeben sich für die beiden Fenster die weiter oben abgebildeten Ausgabe in den Memo-Feldern.

 

IcoDelphi7_36  Download Programm Kontakt1  (Delphi 7):  Kontakt1.zip

 

 
Exkurs: Server und Client auf zwei Rechnern

 

Das vorige und die folgenden Programmierbeispiele sind so angelegt, dass der Serversocket und der Clientsocket im gleichen Programm auf demselben Rechner laufen. Das vereinfacht hier die Programmentwicklung und ermöglicht die Demonstration der Zusammenhänge auf einem einzigen Rechner. Tatsächlich laufen Server- und Client-Programm üblicherweise auf verschiedenen Rechnern.

Zur Demonstration dieses Sachverhaltes dient das Programm Kontakt2. Es besteht aus den beiden Programmen Server2 und Client2, die auf verschiedenen Rechnern gestartet werden können. Im Gegensatz zum vorigen Programm muss der Clientsocket dann noch an die IP Adresse und die Portnummer des Server-Sockets angepasst werden. Das Fenster des Client-Programms hat hierfür zusätzliche Eingabefelder EdAdresse und EdPort.

 

IcoDelphi7_36  Download Programm Kontakt2  (Delphi 7):  Kontakt2.zip

 

Alle noch folgenden Programmbeispiele können - und sollten - in gleicher Weise zu "echten" Client-Server-Anwendungen erweitert werden.

 

   bt_top  

 


(FvSG 30.1.2006)
 
 
Wednesday, 22. November 2017 / 08:04:03