Vortrag über die Netmaster /

 Internet-Komponenten von Delphi

 

© 2001 Tobias Tiedt

 

 

1. Client-Server Modell

Was ist ein Server

Was ist ein Client

 

Kommunikation zwischen den Beiden (Grundbegriffe)

     TCP/IP

     Socket

     Port

     spezielle Dienste

 

2. Komponenten zur Programmierung von Clients und Servern

3. speziell für HTTP-Client / -Server

4. speziell für Mail-Client

 

5. Quellen

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

1. Client-Server-Modell (kurze Einführung)

 

Definition eines Servers:

Ein Server ist im Endeffekt nur ein Rechner, eine Servermaschine, auf der ein Subsystem läuft, eine spezielle Software, welche einen speziellen Dienst oder bestimmte Dienste für Clients implementiert und zur Verfügung stellt, wobei der Client im allgemeinen unbekannt ist.

Diese speziellen Dienste könnten zum Beispiel ein WebServer, ein FTP-Server oder ein Mail-Server oder ein Datenbank-Server sein, welche eine Menge an Operationen (Prozeduren) stellen.

 

Definition eines Clients:

Ein Client ist eine Anwendung, die auf einer sogenannten Clientmaschine läuft, zum Beispiel eine Workstation oder ein simpler PC oder Ähnliches. Diese Clientsoftware initiiert normalerweise eine Anforderung an einen Server und einen bestimmten Dienst oder eines Service dem Benutzer zur Verfügung zu stellen, wie zum Beispiel das WWW mittels eines Webbrowsers.

 

Kommunikation zwischen Client und Server:

 

-         im allgemeinen laufen Client und Server auf getrennten Systemen ab

-         Kommunikation basiert mittels einem Netzwerk mit bestimmten Protokollen

-         Beispiele für Protokolle : TCP/IP, UDP, IPX/SPX

-         im weiteren Verlauf nur Beschäftigung mit dem TCP/IP-Protokoll

 

-         TCP/IP (Transmission Control Protocol / Internet Protocol)

-         im weitern Verlauf nur Beschäftigung mit TCP/IP

 

-         TCP/IP-Netzwerke funktionieren nur mittels direkter Verbindung zwischen Rechnern

-         Client muss mit Server verbunden sein, bevor Datenaustausch in beide Richtungen erfolgen kann

-         eine Maschine muss also als Sender, die andere als Zuhörer konfiguriert sein

 

 

 

-         Unterschied zu UDP (User Datagramm Protocol)

-         UDP ist verbindungsloses Protokoll, wo ein Rechner Daten sendet, ohne Garantie, dass diese Daten auch ankommen

 

-         das TCP/IP-Protokoll packt die zusendenden Daten in Packete

-         bzw. entpackt die Daten

-         schickt dann die Daten übers Netzwerk mittels Adressenangabe im Kopf der einzelnen Packete

-         in einem TCP/IP-Netzwerk, wie zum Beispiel das Internet, stellt der Client Anfrage (request) an Server

-         Server hält den passenden vom Client geforderten Dienst bereit

-         Server schickt dem Client nach Bearbeitung eine Antwort (response)

-         Verbindungsaufnahme aus Sicht eines Clients:

Socket herstellen

                  Adresse und Dienst (Diensteingang: Port) eines Servers herausfinden

                  Verbindung versuchen aufzubauen

                  Verbindung halten, wenn OK des Servers

                  Daten senden und empfangen

                  Socket schließen, wenn fertig

                  Verbindung beenden

-         Verbindungsaufnahme aus Sicht des Servers folgt unter Punkt 3

 

-         Socket (auf Windows-System implementiert durch Wsock32.dll oder Wsock32.lib für C++)

-         erste Entwicklung von Sockets an der Universität von Berkley in Californien für Unix-Systeme

-         dienten anfänglich zur Vereinfachung der Kommunikation zweier Prozesse

-         Konzept wurde dann auch für andere Systeme weiterentwickelt

 

-         ein Socket ist heute der Endpunkt einer TCP/IP-Verbindung

-         Sockets setzen auf dem Protokoll auf und managen den gesamten Ablauf der Verbindung

-         so besitzt der Client einen ClientSocket und der Server einen ServerSocket

 

-         ein erstellter Socket ermöglicht noch keinen Datenaustausch

-         ähnlich wie bei einem Telefon, ein Telefon zu besitzen heißt noch nicht zu telefonieren, man muss erst eine Telefonnummer wählen

-         für Verbindungsaufbau mittels einem Socket ist die Adresse der Application von Nöten, mit der man sich verbinden will

-         diese Adresse beinhaltet drei Teile

-         1. die Protokollfamilie (zB. Die auf TCP/IP aufsetzenden Protokolle (http, ftp, ...))

-         2. die IP-Adresse (einen Hostnamen/Servernamen)

-         3. dessen Servicenummer (Port)

 

-         ein Socket ist deshalb für ein ganz bestimmtes Protokoll und eine ganz bestimmte Adresse und einen ganz bestimmten Service / Dienst zuständig

-         Socket des Client ist für einen Dienst zuständig, zum Bsp. HTTP

-         der ClientSocket nimmt die Verbindung zu einem ServerSocket desselben Typs auf (ähnlich wie eine Telefonnummer zu wählen)

-         Typ wird durch das Protokoll festgelegt

-         Sockets unterschiedlichen Typs können nicht miteinander kommunizieren

-         Socket (ServerSocket) ist zuständig für das „Lauschen“ an einem gewissen Port

-         so laufen keine 2 WebServer parallel auf einem system, da sie am selben Port lauschen

-         akzeptiert der Server den Versuch eines Verbindungsaufbaus von einem Client, dann kreiert der Server einen neuen Socket

-         der alte Socket lauscht indes weiter nach eingehenden Verbindungen

 

-         Ports sind die Ausgänge eines Programms / Rechners

-         ein Rechner besitzt 65536 mögliche Ports, von Port 0 bis Port 65535

-         die ersten Ports sind meistens für das System bestimmt

-         mit diesen Ports sind zum Teil ganz bestimmte Dienste verknüpft

 

-         zum Beispiel: FTP (Port 21), HTTP (Port 80), Gopher (Port 70), SSH (Port 22), POP3 (Port 110), Telnet (standard Port 23) ...

-         diese ganzen bestimmten Dienste fasst das Internet in sich zusammen

-         ein WebBrowser stellt zum Beispiel HTTP dem Nutzer zur Verfügung

-         so verbindet sich der Browser mit einem Server der auf Port 80 lauscht, einen Server, welcher auf anderen Ports lauscht, würde der Browser nie finden, da er ja auch etwas von Port 80 haben will

 

 

2. Delphi und seine Komponenten für Internetanwendungen

 

-         um nun Programme mit Delphi zu schreiben, welche solche Internetdienste realisieren, benötigt man nun diese Sockets, mit denen man mit anderen Programmen und Rechnern kommunizieren kann

-         Delphi besitzt jedoch schon vorgefertigte Komponenten, welche einem die Arbeit erleichtern und man sich nicht mehr zwingend mit Sockets herumplagen muss

-         so sind diese Komponenten zum Teil schon für gewisse spezielle Dienste konzipiert

-         selber jedoch greifen diese Komponenten wieder auf die Sockets zurück

 

-         die meisten dieser Komponenten stammen nicht von Borland (Inprise) sondern sind eine Sammlung von verschiedenen Firmen (insbesondere NetMaster mit seinen FastNet-Komponenten)

-         unter Delphi 4 findet man diese Komponenten erst ab der Professional-Version und dort unter der Palette Internet

-         bei Delphi 5 sind sie unter der Palette FastNet zu finden und es existiert noch eine zweite Palette, Internet, wo weitere Komponenten zu finden sind

-         in Vorversionen waren diese Komponenten von den Firmen gekapselte ActiveX-Steuerelemente

-         wurden jedoch nach und nach auch in Delphi implementiert und sind so effektiver geworden ( aus GoTo Delphi 5)

 

-         als Beispiel für solche Komponenten wäre die NMFtp-Komponente

-         (NM steht dabei immer für Netmaster danach, was diese Komponente eigentlich tut)

-         mittels der NMFtp-Komponente kann man zum Beispiel einen FTP-Client implementieren

-         weitere Beispiele: die NMHttp-Komp. für einen WebBrowser, die NMSmtp-Komp. für einen MailClient, NMUDP, welche es ermöglicht, auf das UDP-Protokoll zuzugreifen und sowohl eine Applikation als Client als auch als Server zu implementieren und somit den Zugang zu UDP-Netzwerken und seinen Diensten zu gelangen

-         mit der NMSmtp-Komponente wird unter Punkt 4 ein MailClient entwickelt

-         unter Punkt 3 ein WebBrowser mit der HTML-Komponente

-         die Komponenten aus der Internet (Delphi 4)-Palette sind meistens dafür gedacht, Clients zu entwickeln

-         ebenso sind aber auch zwei Socket-Komponenten vorhanden

-         TClientSocket und TServerSocket (unter Punkt 3 wird daruas ein WebServer entwickelt)

 

-         zur Entwicklung von Internetprogrammen gibt es also eine Vielzahl an Komponenten

 

 

3. Entwicklung eines WebBrowsers und eines WebServers

 

WebBrowser:

 

-         durch HTTP ist Internet erst populär geworden

-         Entwicklung von Browsers und Servern, welche Daten im netten Layout anzeigten

-         nicht mehr Konsole und tiefes Wissen von Kommandobefehlen -> einfaceh Handhabung

-         dieser Dienst ist mit einem WebBrowser wie Netscape, Opera oder dem Internet-Explorer verfügbar

-         (wobei die oben genannten Browser und noch eine Vielzahl mehr, wesentlich mehr können, als nur html-Dateien aus dem Internet anzuzeigen)

-         HTML (Hyper Text Markup Language)

 

-         um Inhalte (html-Dokumente) aus dem Internet abzurufen ist folgendes zu beachten:

-         mittels Socket muss eine Verbindung zu einem Server aufgebaut werden und eine Anfrage gestellt werden, zB. Gebe mir die Seite default.html aus dem und dem Verzeichnis

-         der Server schaut dann nach ob es diese Datei gibt und schickt sie dem Browser mittels TCP/IP

-         für die Verbindung muss man die Adresse, den Port und die Protokollfamile wissen

 

-         der folgende Ansatz einer Implementierung ist aber ohne Sockets gestaltet

-         was bleibt ist das Wissen um die Adresse und den Dienst, welcher hier die Protokollfamilie und den Port angibt

 

-         die Adresse wäre zum Beispiel eine URL (Uniform Resource Locator), hinter der sich eine IP-Adresse versteckt

 

-         der Dienst HTTP und somit der Port 80

 

-         Implemetierung mittels der Html-Betrachter-Komponente

-          nachdem man die Komponente in seine Form gezogen hat, kann man sich die Eigenschaften und Methoden anschauen

-          die einzige für uns interessante Methode ist RequestDoc, welche bei der an sie übergebene URL/Quelle/Ort nachschaut, ob es etwas zum Anzeigen gibt

-          bei Aufruf der Methode wird das Ereignis DoRequestDoc ausgelöst

-          nun wird die angegebene Adresse aufgelöst und entschieden, um welches Typ URL es sich handelt (File-URL oder HTTP-URL)

-          das Steuerelement wird nun dazu gebracht, die neue Quelle zu akzeptieren

-          ein Nachteil ist, dass die Komponente keine Frames interpretieren kann

-          ebenso tut sich die Komponente schwer mit Bildern, sollte sie eigentlich anzeigen können, tut sie aber des Öfteren nicht

-          das folgende Listing zeigt das minimale Codegerüst

 

Listing: minimaler WebBrowser (Html-Betrachter-Komponente)

 

{auf der Form (Form1) befinden sich die HTML-Komponente (HTML1), ein Button (Button1) und ein Textfeld (Edit1), in dem die URL eingetragen ist / wird}

 

procedure TForm1.Button1Click(Sender: Tobject);

var url: WideString

 

{der Typ WideString repräsentiert einen dynamisch zugewiesenen String mit 16-bit

Unicode-Zeichen  ähnelt sehr dem Typ AnsiString}

 

Begin

            url:= Edit1.Text;

            HTML1.RequestDoc( url );

End;

 

-         man kann WebBrwoser aber auch mittels Socket programmieren

-         dazu benötigt man die Komponente TClientSocket mit ihren Eigenschaften und Methoden

-         TClientSocket verbindet sich mit einem angegeben Server / ServerSocket

-         Danach folgt die Anfrage nach den Dienstleistungen, je nach Einstellung des ClientSockets

-         der Server bearbeitet die Anfrage und schickt eine Antwort zurück

-         um die Antwort interpretieren zu können, sprich anzeigen, ist wieder der HTML-Betrachter der HTML-Komponente gefragt

-         andere Komponenten stehen standardmäßig unter Delphi4 nicht zur Verfügung

 

WebServer:

 

-         der folgende Abschnitt beschäftigt sich näher mit Sockets am Beispiel eines WebServers

 

-         Funktionalität eines Webservers ist es zu horchen

-         in Webserver stellt den Dienst HTTP zur Verfügung

-         er muss jedoch erst mal wissen, wann er seinen Dienst ausführen kann

-         deshalb „lauscht“ er an dem für ihn wichtigsten Port 80 und wartet bis ein Client sich mit ihm verbinden will

-         leistungsfähige WebServer erstellen einen neuen ServerSocket, sobald ein Client (WebBrowser) sich mit ihnen verbunden hat

-         der neue Socket bedient den Client und bearbeitet seine Anfragen, während der ursprüngliche Socket weiter lauscht

-         bei Beendigung der Verbindung wird der bis dato lauschende Socket geschlossen und der bis dahin den Client bedienenden Socket legt sich stattdessen auf die Lauer

-         das Handling mehrerer Sockets kann sich recht kompliziert gestalten, deshalb wird im Beispiel darauf verzichtet und nur mit einem Socket gearbeitet

-         wie sich der EinSocket-Server äußert, wenn mehrere Clients sich mit ihm verbinden wollen, wird noch erläutert

 

-         jenes Lauschen ist durch eine Endlosschleife realisiert, welche solange durchgelaufen wird, bis Clientanfrage, danach wird die Endlosschleife wieder durchgegangen

-         für die Realisierung des Servers unter Delphi hilft uns die TServerSocket-Komponente weiter

-         die Komponente besitzt die Methode Listen(), durch welche die Endlosschleife realisiert wird

-         eine wichtige Eigenschaft ist Port, welche angibt, auf welchem Port der Server zu lauschen hat

-         (die Eigenschaft kann man nur zur Entwurfszeit ändern und nicht zur Laufzeit)

-         entweder man gibt dort den Port ein oder man trägt bei Service einen Standarddienst ein, wie zum Beispiel HTTP, FTP, Finger (Port 79), Time ... (der Port wird dann automatisch festgelegt)

-         um nun den Ablauf zwischen ServerSocket und einem Client abläuft, schaut man sich die Methoden genauer an

-          OnListen()

-          OnAccept()

-          OnClientConnect()

-          OnClientWrite()

-          OnClientRead

 

-         OnListen wird immer dann ausgeführt, wenn die Eigenschaft von TServerSocket Active auf true gesetzt ist, was schon im Objektinspektor getan werden kann, so dass er sofort wenn er gestartet ist, lauscht

-         Will sich ein Client verbinden wird die Methode OnClientConnect aufgerufen

-         Wenn der Server nichts zu tun hat außer Lauschen, dann wird sofort nach OnClientConnect OnAccept aufgerufen

-         Da hier nur ein Socket verwendet wird und kein weitere erzeugt wird, kann nur ein Client bedient werden

-         Wenn ein zweiter Client sich mit unserem WebServer verbinden will, muss er solange warten, bis der erste Client alle Daten erhalten hat

-         An der Stelle, wo ein zweiter Client ins Spiel kommt, wird normalerweise ein weiterer Socket generiert

 

-         in unserem Beispielprogramm wird aus der OnAccept-Methode die Prozedur SendingInformationToBrowser() aufgerufen

-         die OnAccept-Methode wird aufgerufen, wenn der Server die Verbindung mit dem Client akzeptiert und aufrechterhält

-         nach dem Senden der Daten aus der Beispiel-Html-Datei wird das Ereignis OnClientRead ausgelöst, da der Client nun von uns liest

-         beim Senden der Daten sind allerdings einige Dinge zu beachten

-          Html-Code kann mit der Funktion SendText zum Client geschickt werden

-          Bilddateien müssen allerdings mit SendStream oder SendBuf zum Client geschickt werden

-          dazu müssen die Daten aber erst binär aus der Bilddatei gelesen werden

-          sind Bilder in der Html-Datei angegeben versuch der Client sich noch mal mit dem Server zu verbinden, doch dieser hat keine Sockets mehr zur Verfügung, deshalb wird die Anfrage nach den Bildern nicht bearbeitet

 

Listing: minimaler WebServer (mittels TServerSocket)

 

{auf der Form Form1 befinden sich ein Memofeld (Memo1), und ein ServerSocket (ServerSocket1)}

 

Procedure TForm1.ServerSocket1Accept(Sender: TObject; Socket: TCustomWinSocket);

begin

Memo1.lines.Add( ‘OnAccept() ‘ );

SendingInformationToBrowser();

Memo1.lines.Add(serversocket1.socket.connections[0].receivetext + chr(10));

ServerSocket1.Socket.Connections[0].Close;

end;

 

 

Procedure SendingInformationToBrowser();

 

var      theFile:string;

theInfo:string;

theSendInfo:string;

html_doc:textfile;

 

 

begin

//Initialisierung

theFile:= '';

theInfo:= '';

theSendInfo:= '';

 

Form1.Memo1.Lines.Add( 'SendingInformationToBrowser' );

 

theFile := 'data\ws_test.html';

 

AssignFile(html_doc, theFile);  {Datei an html_doc zuweisen}

FileMode := 0;                        { Datei mit Schreibschutz versehen.}

Reset(html_doc);                                 {Datei öffnen}

 

repeat

readln(html_doc,theInfo); //aus Datei lesen

theSendInfo:=theSendInfo + theInfo + chr(10) +chr(13);

//Datei inhalt

//zeilenweise in

//einen string

//speichern

until EoF(html_doc);

 

CloseFile(html_doc); //Datei schließen

 

form1.serversocket1.socket.connections[0].SendText(theSendInfo);

//daten senden

 

end;

//end of procedure

 

 

 

 

 

4. Entwicklung eines MailClient

-    ein weiterer sehr oft genutzter Dienst, wenn nicht sogar der meistgenutzte ist der der

e-Mails

 

-         die wichtigsten Protokolle auf denen der Dienst basiert sind

-         SMTP (Simple Mail Transfer Protocol) zum Mails verschicken

-          POP3 zum Mails empfangen bzw. Herunterladen

-         für ein Programm, welches e-Mails verschicken kann, stellt Delphi die NMSMTP-Komponente zur Verfügung

-    damit eine e-Mail gesendet werden kann, benötigt man einen Postausgangsserver und meistens eine User_ID

-         der Port, über den dies abgewickelt wird, ist standardmäßig Port 25 bei SMTP

-         der Server wird die e-Mail nun weiterleiten wollen

-         damit er dies kann, benötigt er die Angabe einer Adresse (die e-MailAdresse)

-         die restlichen Informationen wie Subject und Kopie an ... können ihm ebenfalls übermittelt werden, sind aber nicht lebensnotwenig

 

-         wenn die e-Mail gesendet wird, wird dieses mit der Komponenten-methode Connect gemacht

-    in dem folgenden Beispiel wird aber diese Methode nicht direkt aufgerufen

-    es wird hingegen auf das Ereignis ConnectRequiered reagiert

-    das Ereignis wird immer dann ausgelöst, wenn man nicht mit dem Server verbunden ist, oder die Verbindung abgebrochen ist und in der Ereignisroutine wird die Methode Connect aufgerufen

-    im Beispiel werden die benötigten Informationen über Adresse ... in der OnClick des SendeButtons getätigt

-    die einzelnen Eigenschaften sind Untereigenschaften von NMSMTP.PostMessage

-    FromAddress ist der Absender, welcher unbedingt angegeben werden muss

-    ToAddress ist der Empfänger, welcher ebenfalls unbedingt angegeben werden muss

-    Subject ist der Titel der e-Mail

-    Body ist der Rumpf der e-Mail

-    ToCarbonCopy  Kopie an

-    ToBlindCarbonCopy  Blindkopie an

-         die Empfängeradresse genauso wie der Body werden als Stringliste importiert und

sollten deshalb vorher gelöscht werden (mittels NMSMTP.PostMessage.Body.Clear)

-         tut man dies nicht, so werden die neuen Informationen immer an die alten gehängt,

so würde jedes Mal eine neue Adresse hinzugefügt werden, das beispiel begnügt sich aber mit einer möglichen Adresse

-         möchte man noch die Möglichkeit der Anhänge (Attachments) implementieren,

-         so hat dies folgendermaßen auszusehen

 

...

with NMSMTP.PostMessage do

begin

      ...

      Attachments.Clear;

Attachments.Add(path);

end;

 

-         Attachments können nur als Datei angehängt werden und versendet werden

-         deshalb muss man bei Attachments.Add(path) einen Dateipfad angeben

 

-         im Beispiel wird sich aber nicht mit Attachments „abgemüht“

-         das folgende Listing zeigt nun einen minimalen MailClient zum Versenden von

Mails ohne Attachments

 

 

 

Listing: minimaler MailClient (mittels NMSMTP)

 

{auf der Form befinden sich zwei Textfelder (Edit1 für die Empfängeradresse, Edit2 für das Subject), ein Richtextfeld (RichEdit1 für den Body) und ein Button (Button1) und eine NMSMTP-Komponente (SMTP)}

 

procedure TForm1.Button1Click(Sender: TObject);

begin

with SMTP.PostMessage do

begin

FromAddress :=  'Horst@Klaus.gov' ;

ToAddress.Clear;

ToAddress.Add(Form1.Edit1.Text);

Subject := Form1.Edit2.Text;

Body.Clear;

Body.AddStrings(Form1.RichEdit1.Lines);

SMTP.SendMail;

end;

end;

 

procedure TForm1.SMTPConnectionRequired(var Handled: Boolean);

begin

//weil der Sendversuch aus der procedure Button1.Click fehlgeschlagen ist,

//ist es wichtig, den Variablenparameter Handled auf true zu setzen, damit der

//Sendeversuch wiederholt wird

Handled := True;

 

//Eintragen des Host / Mailservers und der UserID

with SMTP do

begin

Host := 'nikotinsucht.krebs.edu';

UserID := 'horst';

end;

 

//verbinden

SMTP.Connect;

end;

 

 

 

 

 

5. Quellen

 

Internet:

 

(Client-Server-Modell)

http://www11.informatik.tu-muenchen.de/lehre/lectures/va-SS97/vorlesung-ss1997/chap_3/chap3-3.html  

 

(Server, Webserver)

http://www.nls.at/~wsa/cyclon2/server_neu.html

 

(TCP/IP, UDP, Socket, SocketProgrammierung)

http://www.catalyst.com

 

 

Bücher:

 

Programmier-Workshop Visual Basic 6

            (Wayne S. Freeze) Sybex-Verlag (ISBN: 3 8155 7286 x)

 

GoTo Delphi 5

(Andreas Bohne, Guido Lang)  Addison-Wesley-Verlag (ISBN: 3 8273 1568 9)

 

GoTo Delphi 4

(Andreas Bohne, Guido Lang)  Addison-Wesley-Verlag (ISBN: 3 8273 1373 2)

 

 

6.Downloads

 

WebServer

WebBrowser

MailClient