kopf
brlogo
fensterobenrechts
   
   
fensteruntenblau
   
 
header
 

bt_backward   bt_index   bt_forward

Ein kleines Chat-Programm

 

Chat (v. engl. to chat  plaudern) ist die Bezeichnung für die innerhalb des Internet weit verbreitete Art der direkten Unterhaltung zwischen zwei oder mehreren Personen in Echtzeit. Es ist eine Art Computerkonferenz, die meist allerdings ohne Bilder auskommt. Stattdessen gebrauchen Teilnehmer, die zusammen "chatten", daher neben dem geschriebenen Wort auch Ersatzbilder (Avatare, Emoticons). Man trifft sich meist in Chatrooms zu verschiedenen Themen. Eine besondere Form sind die Webcam-Chats, bei denen man sich über Webcams sieht.

(aus WIKIPEDIA - die freie Enzyklopädie)

 

 

chat_20

Programm Chat1

 

Im Programm steht die Verwaltung von Clientsockets in einem Serversocket im Vordergrund. Am Chat-Server können sich mehrere Chat-Clients anmelden, die dann untereinander Nachrichten austauschen können. Jede Verbindung erfordert einen eigenen Socket. Daher besteht der Unterschied zwischen einer Serversocket-Komponente und einer Clientsocket-Komponente im Wesentlichen darin, dass eine aktive  Serversocket-Komponente

  • immer einen Socket für die Kontaktaufnahme offen hat, ferner dass sie
  • für jeden Client, der sich anmeldet, einen weiteren Socket bereitstellt.

Im Gegensatz zu echten Chat-Protokollen (z. B. das IRC Protoll, IRC = Internet Relay Chat), die in der Regel Zeichenketten mit einem festen Aufbau verwenden, wird hier eine Datenstruktur (Record TChatNachricht) verwendet, um die Funktionen SendBuf und ReceiveBuf vorzustellen.

 

Einige Merkmale des Programms Chat1:

 

  • Clients melden sich unter einem Namen an (Nickname), der den Teilnehmer eindeutig identifiziert. Der Anmeldename kann frei gewählt werden.
  • Der Chat-Server informiert alle gerade angemeldeten Teilnehmer über einen neuen Teilnehmer am Chat, das neue Mitglied erhält eine Liste der Namen aller übrigen Teilnehmer.
  • Der Server führt ein Protokoll aller Nachrichten (nur Sender und Empfänger, nicht die Nachricht selbst).

 

Das Programm dient der Darstellung der benötigten Techniken. Es ist nicht praxistauglich, da es keinerlei Schutzmechanismen für Fehler beinhaltet, z. B.

 

  • Anmeldung: Jeder Anmeldename muss den Teilnehmer eindeutig identifizieren. Es gibt aber keine Überprüfung eines gültigen Anmeldenamens.
  • Timing: An- und Abmeldung, Versand von Nachrichten kann nicht zeitlich verschränkt erfolgen, da keine "Serialisierung" der Aktionen vorgenommen wird.
  • Timing: Die Ausführungszeit der einzelnen Aktionen wird nicht berücksichtigt. In der Lernumgebung eines Schulnetzes werden die einzelnen Aktionen hinreichend schnell ausgeführt, in der harten Realität des Internets ist das nicht immer gewährleistet.

 

Es gibt also noch genügend Möglichkeiten, dieses Programm zu verbessern.

 

 

Ein Datensatz für die Kommunikation

 

Die hier verwendeten Datenpakete enthalten neben der eigentlichen textuellen Nachricht noch den Anmeldenamen (Nickname) des Senders. Im Gegensatz zum weit verbreiteten IRC Protokoll, bei dem sämtliche übertragenen Informationen mit in dem Nachrichten-String codiert werden, wird hier ein Datenpaket als Datenstruktur übertragen.

 

TChatNachricht = Record
  Nickname: string[255];
  Text:     string[255]
end;
 

 

Übertragen von Datenpaketen des Typs TChatNachricht

 

Die Übertragung eines solchen Datensatzes mithilfe der Methoden SendBuf und ReceiveBuf geschieht byteweise und unstrukturiert.

 

function SendBuf (var Buf; Count: Integer): Integer;
Schreibt einen beliebigen, unstrukturierten, nicht typisierten Datenbereich Buf (= 'Buffer') in die Socketverbindung. Bei der Datenübertragung ist immer die Länge Count der Daten (= Anzahl Bytes) anzugeben, damit der Empfänger weiß wie groß die Datenmenge ist.
 
function ReceiveBuf (var Buf; Count: Integer): Integer;
Liest einen beliebigen, unstrukturierten, nicht typisierten Datenbereich Buf (= 'Buffer') der Länge Count (Bytes) aus der Socketverbindung.
 

Einige Hinweise zur Verwendung dieser Methoden:

 

  • Die übertragenen Daten werden in den Sockets zwischengepuffert. Wird mit ReceiveText bzw. ReceiveBuf ein Datensatz gelesen, wird er anschließend  aus diesem Puffer entfernt. Ein weiteres Lesen dieser Informationen aus dem Socket ist nicht möglich.

  • Mithilfe der Systemfunktion function SizeOf (X): Integer kann der für einen untypisierten Datenbereich X benötigte Speicherplatz (= Anzahl Bytes) ermittelt werden. Beispiel:  SendText ('Hallo') ist also identisch mit SendBuf ('Hallo', SizeOf ('Hallo')).

  • Die Verwendung von SendBuf und ReceiveBuf setzt voraus, dass diese benötigte Speicherplatz konstant ist und vorher berechnet werden kann. Sogenannte 'Null-terminierte Strings' (String-Format für Programmiersprache C und Abkömmlinge) haben eine unbestimmte Länge. Verwenden Sie möglichst 'Pascal-Strings'. Beispiel:  var Zeichenfolge: string [255].

  • Die Funktionen SendBuf und ReceiveBuf können 'Turbo-Pascal-typisch" auch prozedural verwendet werden. Als Funktion liefern sie über ihren  Funktionswert die Anzahl der tatsächlich übertragenen Bytes oder den Wert -1, falls keine Übertragung stattfand.
 

 

Beispiel:  Senden einer Chat-Nachricht

 

Beim Drücken der Schaltfläche BtSenden wird der Anmeldename aus dem Edit-Feld EdNickname und die Nachricht im Editfeld EdSenden an den Chat-Server gesendet.

 

procedure TFrmClient.BtSendenClick(Sender: TObject);
var Nachricht: TChatNachricht;
begin Nachricht.Nickname := EdNickname.Text;
  Nachricht.Text := EdSenden.Text;
  ClientSocket.Socket.SendBuf (Nachricht, SizeOf(Nachricht));
end;
Datenpaket
 
initialisieren, dann

senden
 

 

Beispiel:  Anmelden und Abmelden beim Chat-Server

 

Meldet sich ein neuer Teilnehmer beim Chat-Server an, wird für ihn ein neuer Socket angelegt und das Ereignis OnConnect ausgelöst. Der Chat-Server reagiert auf dieses Ereignis, indem er

  • dem neuen Teilnehmer einen Willkommensgruß als Bestätigung der Anmeldung sendet, und
  • allen anderen Teilnehmern die Anzahl der gerade angemeldeten Teilnehmer mitteilt.
 
procedure TFrmServer.ServerSocketClientConnect (Sender: TObject; Socket: TCustomWinSocket);
var Nachricht: TChatNachricht;
    var I: Integer;
begin
  MemStatus.Lines.Add ('Status: Neuer Client verbunden');
  Nachricht.NickName := 'Server';
  Nachricht.Text := 'Willkommen am Chat-Server';
  Socket.SendBuf (Nachricht, SizeOf(Nachricht));
  with ServerSocket.Socket do begin
    Nachricht.Nickname := 'Server';
    Nachricht.Text := 'Jetzt ' + IntToStr(ActiveConnections) + ' Teilnehmer';
    for I := 0 to ActiveConnections-2 do
      Connections[I].SendBuf (Nachricht, SizeOf(Nachricht))
  end; {with}
end;





Willkommensgruß



Info
 

 

Verwalten der Client-Sockets im Server-Socket

 

Der Programmausschnitt oben zeigt auch zugleich die Verwaltung der einzelnen Sockets in der Serversocket-Komponente:

 

  • Eine aktive Serversocket-Komponente hat einen geöffneten Socket, dem ihr Port fest zugeordnet ist. Über diesen Port kann nun ein Clientsocket Kontakt mit der Komponente aufnehmen.

  • Ist dieser Kontakt hergestellt, erzeugt die Server-Komponente für diesen Client einen weiteren Socket, weist ihm einen Port dynamisch zu und verwaltet diesen Port in der internen Verwaltungsstruktur Connections. Die Eigenschaft ActiveConnections gibt die Anzahl der gerade verwalteten Sockets an.

  • Diese Verwaltungsstruktur ist intern eine dynamische Feldstruktur FConnections der Klasse TList. Ein neue Socket wird eingefügt, indem er als derzeit letzter Socket hinten angehängt wird (= dynamische Strktur). Auf die einzelnen Sockets kann indiziert zugegriffen werden (= Feldstruktur). Der Index beginnt immer bei 0. Der erste Socket hat also die Nummer 0, der letzte die Nummer ActiveConnections-1.

  • Die Sockets-Objekte in dieser Verwaltungsstruktur sind von der Klasse TClientWinSocket, die einen Server- oder Clientsocket als Objekte kapseln.
 

Typische Zugriffmechanismen auf die Socket-Verwaltung

 

Anzahl der verwalteten Sockets:

 

if (ServerSocket.Socket.ActiveConnections > 0)
  then begin
      {Client-Sockets sind mit dem Server verbunden} end;
 

Indizierter Zugriff:

Die Nummerierung der Sockets beginnt immer bei 0. Der 4. Socket hat also den Index 3. Voraussetzung: ActiveConnections >= 4.

 

ServerSocket.Socket.Connections[3].SendText ('Nachricht an 4. Socket');
 

Iteration über alle Sockets:

Eine Nachricht an alle verbundenen Clients (wie z. B. im Programm Chat1) wird damit in der Regel mithilfe einer Schleife über diese Feldstruktur realisiert:

 

For I := 0 to ServerSocket.Socket.ActiveConnections-1 do begin
  ServerSocket.Socket.Connections[I].SendText (' ... ');
    ...end;
 

Detailliertere Informationen zu den an der Verwaltung der Sockets beteiligten Klassen finden Sie z. B. in der Beschreibung der Klasse TServerSocket.

 

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

 

 

Mögliche Erweiterungen von Programm Chat1

 

Hier endet nun die Beschreibung der Möglichkeiten und Techniken, die das Programmiersystem Delphi in Form der Komponenten TServerSocket und TClientSocket zur Verfügung stellt. "Algorithmisch" wird das Thema an dieser Stelle jetzt erst richtig interessant.

 

Als Beispiel betrachten wir die folgende mögliche Erweiterung:

 

Programm Chat2: Der Benutzer eines solchen Chat-Programms kann einem der aktiven Chat-Teilnehmer eine private Nachricht schicken.
 

 

chat_30

 

 

Für dieser Erweiterung ergibt sich im Gegensatz zur "Sammelnachricht an alle" des Programms Chat1 die Notwendigkeit, Teilnehmer (Sender wie Empfänger) gezielt zu identifizieren und über "Ihren" Socket anzusprechen. Der Server muss also z. B. die Anmeldenamen aller verbundenen Clients verwalten, die Eindeutigkeit des Nicknamens garantieren, diesen Teilnehmer über "seinen" Socket" ansprechen können usw.

Vielleicht wird man hierzu die hier vorgestellten Record-Struktur TChatNachricht um weitere Bestandteile erweiteren müssen, oder man verabschiedet sich von dieser Datenstruktur und verwendet statt dessen das im Internet weit verbreitete IRC Protokoll.

In jedem Fall treten jetzt die Techniken der Socket-Kommunikation in den Hintergrund, und die für komplexere Client-Server-Anwendungen notwendigen Kommunikationsprotokolle stehen im den Mittelpunkt der Betrachtungen.

 

   bt_top  

 


(FvSG 30.1.2006)
 
 
Thursday, 23. November 2017 / 21:37:32