Previous Page TOC Index Next Page See Page

18

Sockets, MAPI und das Internet

Damit Ihre Anwendungen mit anderen Anwendungen über ein Netzwerk wie dem Internet kommunizieren können, stehen Ihnen verschiedene Methoden zur Verfügung. Das vorliegende Kapitel bietet eine Einführung in die Konzepte, die diesen Programmiertechniken zugrunde liegen. In den nachfolgenden Kapiteln werden einige dieser Konzepte etwas genauer betrachtet.

Noch bevor das Betriebssystem Windows überhaupt existierte, gab es bereits das Internet. Es wuchs immer mehr und wurde zum größten TCP/IP-Netzwerk der Welt. Die frühen Sites waren Unix-Rechner, und eine Sammlung von Konventionen û die sogenannten Berkeley-Sockets û wurden die Norm für die TCP/IP-Kommunikation zwischen Unix-Rechnern im Internet. Andere Betriebssysteme implementierten ebenfalls TCP/IP, was beträchtlich zum Wachstum des Internet beitrug. Auf diesen Betriebssystemen begann das Durcheinander, da eine große Bandbreite proprietärer TCP/IP-Implementierungen entstand, bis eine Gruppe von über 20 Herstellern sich für die Erstellung der Winsock-Spezifikation zusammenschloß.

Windows Sockets

Die Winsock-Spezifikation definiert die Schnittstelle einer DLL, die typischerweise WINSOCK.DLL oder WSOCK32.DLL genannt wird. Die Hersteller schreiben den Code für die Funktionen selbst. In Anwendungen lassen sich diese Funktionen aufrufen, wobei man sichergehen kann, daß der Name, die Bedeutung der Parameter und das letztendliche Verhalten der Funktion immer gleich sind û und zwar unabhängig davon, welche DLL auf Ihrem System installiert ist. So werden unter Windows 95 und Windows NT beispielsweise unterschiedliche DLLs bereitgestellt. Und dennoch kann eine 32-Bit-Winsock-Anwendung unverändert sowohl unter Windows 95 als auch unter Windows NT ausgeführt werden, denn in der Anwendung werden die Winsock-Funktionen in der entsprechenden DLL aufgerufen.


Winsock ist nicht auf die TCP/IP-Kommunikation beschränkt. IPX/SPX ist das zweite unterstützte Protokoll; weitere werden folgen. Weitere Informationen hierzu erhalten Sie aus der Winsock-Spezifikation selbst. Die Winsock Resource Page der Stardust Labs unter http://www.stardust.com/wsresource/ ist hierfür ein guter Ausgangspunkt.

Ein wichtiges Konzept bei der Sockets-Programmierung ist der Port eines Socket. Jede Site im Internet besitzt eine numerische Adresse, die sogenannte IP-Adresse, die typischerweise in Form von vier, durch Punkte getrennten, Zahlen geschrieben wird, z.B. 198.53.145.3. Programme, die auf dem betreffenden Rechner ausgeführt werden, können mit Hilfe von Sockets mit anderen Rechnern Daten austauschen. Wenn nun bei 198.53.145.3 eine Anfrage eintrifft, von welchem Programm sollte diese dann bearbeitet werden?

Anfragen kommen bei dem Rechner mit einer Port-Nummer an, die das Programm bezeichnet, an das die Anfrage gerichtet ist. Einige Port-Nummern sind für Standarddienste reserviert, Port 80 etwa wird von Web-Servern traditionellerweise für die Reaktion auf Dokumentanfragen verwendet, die von Client-Programmen wie dem Netscape Navigator kommen.

Der größte Teil der für die Socket-Programmierung anfallenden Arbeit ist verbindungsbezogen: Die beiden Programme bilden eine Verbindung mit je einem Socket an jedem Ende und senden und empfangen dann Daten entlang dieser Verbindung. Einige Anwendungen ziehen es vor, Daten ohne Verbindung zu senden, doch besteht in diesem Fall keine Garantie, daß die Daten ankommen. Das klassische Beispiel ist ein Zeit-Server, der in regelmäßigen Abständen an alle Rechner in seiner Umgebung die aktuelle Uhrzeit sendet, ohne auf eine Anfrage für diese Information zu warten. Die Verzögerung, die durch den Aufbau einer Verbindung entstünde, würde möglicherweise ein Senden veralteter Daten (der falschen Uhrzeit) zur Folge haben û in diesem Fall ist also ein verbindungsunabhängiger Ansatz vorzuziehen.

Winsock und MFC

Zunächst bedeutete die Sockets-Programmierung in Visual C++ eine Implementierung von API-Aufrufen in die Winsock-DLL. Viele Entwickler erstellen Socket-Klassen, um diese Aufrufe zu kapseln. Visual C++ 2.1 stellte zwei neue Klassen vor: CAsyncSocket und CSokket, die von CAsyncSocket abgeleitet ist. Diese Klassen übernehmen die Verarbeitung der API-Aufrufe, einschließlich der Start- und Bereinigungsaufrufe, die man ansonsten leicht vergißt.

Die Windows-Programmierung ist asynchron. Es geschehen viele Dinge gleichzeitig. Wenn in älteren Windows-Versionen ein Teil einer Anwendung in einer Schleife oder auf andere Weise hängenblieb, blieb gleich die gesamte Anwendung û und manchmal sogar das gesamte System û hängen. Dies war offensichtlich ein Zustand, den es unter allen Umständen zu zu unterbinden galt. Ein Socket-Aufruf, etwa ein Aufruf, der über eine TCP/IP-Verbindung mit einem anderen Site des Internet das Lesen von Informationen erlaubt, kann für seine Ausführung einige Zeit in Anspruch nehmen. (Man spricht davon, daß eine Funktion, die auf das Senden oder Empfangen von Informationen wartet, blockiert.) Es gibt drei Möglichkeiten, um dieses Problem zu umgehen:

Möglichkeit 1 war bis vor kurzem noch nicht verfügbar, und Möglichkeit 2 ist unter Windows ineffizient. Daher hat sich für den größten Teil der Winsock-Programmierung die Möglichkeit 3 eingebürgert. Die Klasse CAsyncSocket implementiert diesen Ansatz. Um etwa eine Zeichenfolge über einen verbundenen Socket zu einer anderen Internet-Site zu senden, rufen Sie die Send-Funktion dieses Socket auf. Send muß nicht unbedingt Daten senden; vielmehr macht es den Versuch einer Datenübertragung, doch wenn der Socket nicht bereit ist, liefert es einen entsprechenden Rückgabewert. Ist der Socket bereit, wird dem Socket-Fenster eine Nachricht geschickt, das diese Nachricht abfängt und die Daten überträgt. Man nennt dieses Verfahren eine asynchrone Winsock-Programmierung.


Die Winsock-Programmierung ist kein einfaches Thema; hierzu wurden schon ganze Bücher geschrieben (Internet Applikationen mit Visual C++ erschienen bei Martkt&Technik.)

CAsyncSocket: Die Klasse CAsyncSocket ist eine Wrapper-Klasse für asynchrone Winsock-Aufrufe. Wrapper sind eine zusätzliche Schicht zwischen komplexen, schwierig zu handhabenden Funktionsgruppen und der Anwendung und bilden ein einfacheres API. CAsyncSocket besitzt eine Reihe praktischer Funktionen, die die Verwendung der Winsock-API erleichtern. Tabelle 18.1 ist eine Liste der CAsyncSocket-Mitgliedsfunktionen und -Zuständigkeiten.

Tabelle 18.1: Mitgliedsfunktionen der Klasse CAsyncSocket (Forts.)

Methode

Beschreibung

Accept

Verarbeitet die an einem Socket in Wartestellung eingehende Verbindung und füllt einen neuen Socket mit der Adreßinformation.

AsyncSelect

Fordert das Senden einer Windows-Nachricht an, wenn ein Socket bereit ist.

Attach

Hängt einer CAsyncSocket-Instanz ein Socket-Handle an, so daß eine Verbindung zu einem anderen Rechner hergestellt werden kann.

Bind

Verbindet eine Adresse mit einem Socket.

Close

Schließt den Socket.

Connect

Verbindet den Socket mit einer entfernten Adresse und einem Port.

Create

Beendet den vom Konstruktor begonnenen Initialisierungsprozeß.

Detach

Entfernt ein zuvor angehängtes Socket-Handle.

FromHandle

Liefert einen Zeiger auf den mit dem angegebenen Handle verbundenen CAsyncSokket.

GetLastError

Liefert den Fehlercode des Socket. Durch Aufruf von GetLastError nach einer erfolglosen Operation können Sie den Grund des Fehlschlagens der Operation herausfinden.

GetPeerName

Ermittelt die IP-Adresse und Port-Nummer des entfernten Socket, mit der die aufrufende Objekt-Socket verbunden ist, oder füllt eine Socket-Adressenstruktur mit dieser Information.

GetSockName

Liefert die IP-Adresse und Port-Nummer dieses Socket oder füllt eine Sokket-Adressenstruktur mit dieser Information.

GetSockOpt

Liefert die aktuelle Einstellung der Socket-Optionen.

IOCtl

Setzt den Modus des Socket, meist auf blockierend oder nicht-blockierend.

Listen

Weist einen Socket an, auf eingehende Verbindungen zu warten.

OnAccept

Verarbeitet die Windows-Nachricht, die generiert wird, wenn bei einem Socket eine zu akzeptierende Verbindung eingeht. Wird oft durch abgeleitete Klassen überschrieben.

OnClose

Verarbeitet die Windows-Nachricht, die generiert wird, wenn ein Socket geschlossen wird. Wird oft durch abgeleitete Klassen überschrieben.

OnConnect

Verarbeitet die Windows-Nachricht, die generiert wird, wenn zu einem Socket eine Verbindung aufgebaut wurde oder ein Verbindungsversuch fehlschlägt. Wird oft durch abgeleitete Klassen überschrieben.

OnOutOfBandData

Verarbeitet die Windows-Nachricht, die generiert wird, wenn bei einem Socket wichtige Out-of-band-Daten eingegangen sind.

OnReceive

Verarbeitet die Windows-Nachricht, die generiert wird, wenn bei einem Socket Daten eingegangen sind, die man mit Receive lesen könnte. Wird oft durch abgeleitete Klassen überschrieben.

OnSend

Verarbeitet die Windows-Nachricht, die generiert wird, wenn ein Socket bereit ist für die Annahme von Daten, die man mit Send versenden könnte. Wird oft durch abgeleitete Klassen überschrieben.

Receive

Liest Daten aus dem entfernten Socket, mit denen dieser Socket verbunden ist.

ReceiveFrom

Liest ein Datagramm aus einem verbindungslosen, entfernten Socket.

Send

Sendet Daten an den entfernten Socket, mit denen dieser Socket verbunden ist.

SendTo

Sendet ein Datagramm ohne eine Verbindung.

SetSockOpt

Dient zum Einstellen von Socket-Optionen.

ShutDown

Hält den Socket offen, verhindert jedoch weitere Send- oder Receive-Aufrufe.

Wenn Sie die Klasse CAsyncSocket verwenden, werden Sie die Socket-Adressenstrukturen selbst ausfüllen müssen û doch würden viele Entwickler den Großteil dieser Arbeit gern delegieren. In diesem Fall ist CSocket die geeignetere Socket-Klasse.

CSocket: Die Klasse CSocket ist von CAsyncSocket abgeleitet und verfügt somit über alle für CAsyncSocket aufgelisteten Funktionen. In Tabelle 13.2 werden diese neuen Methoden beschrieben sowie die virtuellen Methoden, die in der abgeleiteten CSocket-Klasse überschrieben werden.

Tabelle 18.2: OnMessagePending Verarbeitet die Windows-Nachricht, die für andere Bereiche Ihrer Anwendung generiert wurde, während der CSocket-Methoden (Forts.)

Methode

Beschreibung

Attach

Hängt einer CSocket-Instanz ein Socket-Handle an, so daß eine Verbindung zu einem anderen Rechner hergestellt werden kann.

Create

Beendet die Initialisierung, nachdem der Konstruktor einen leeren Socket erstellt hat.

FromHandle

Liefert einen Zeiger auf den mit dem angegebenen Handle verbundenen CSocket.

IsBlocking

Liefert den Wert TRUE, wenn der Socket gerade blokkiert ist und auf eine Aktion wartet.

CancelBlockingCall

Bricht die Anfrage ab, die den Socket blockiert hat.

OnMessagePending

Verarbeitet die Windows-Nachricht, die für andere Bereiche Ihrer Anwendung generiert wurde, während der Socket blockiert ist. Wird oft durch abgeleitete Klassen überschrieben.

In vielen Fällen ist keine spezielle Socket-Programmierung mehr erforderlich, da die WinInet-Klassen, die ISAPI-Programmierung und ActiveX-Steuerelemente für Web-Seiten dem Internet-Programmierer immer mehr Leistung bereitstellen. Wenn Sie ein Beispiel-Socket-Programm erforschen wollen, probieren Sie einmal die mit Visual C++ gelieferten Programme Chatter und ChatSrvr aus. Suchen Sie im Hilfesystem nach einem der beiden Namen, oder öffnen Sie die Dateien auf der CD in den Orndern DevStudio\VC\Samples\MFC\Advanced\Chatter und DevStudio\VC\Samples\MFC\Advanced\Chatsrvr.

Jede Chatter-Sitzung emuliert einen Anwender-Server. Das Programm ChatSrvr ist der Server, der als Traffic-Manager zwischen verschiedenen Clients fungiert. Jeder Chatter kann an ChatSrvr Nachrichten senden û durch Eingabe von Text û, und ChatSrvr sendet die Nachricht an alle, die sich während dieser Sitzung angemeldet haben. Es werden mehrere Traffic-Channels gleichzeitig verwaltet.

Wenn Sie bereits mit Sockets gearbeitet haben, mag diese Kurzübersicht als Einstiegsinformation genügen. Wenn nicht, brauchen Sie es vielleicht nie zu lernen. Wenn Sie die Programmierung einer Client-/Server-Anwendung planen, die über das Internet ausgeführt wird, doch keine der vorhandenen Standardanwendungen wie E-Mail oder Web verwendet, so werden Sie sich künftig wohl mit dem Erlernen der Socket-Programmierung befassen müssen. Doch für den Einsatz von E-Mail, Web, ftp und anderen verbreiteten Internet-Informationsquellen brauchen Sie überhaupt keine Socket-Programme zu schreiben. Häufig können Sie für die erwünschten Ergebnisse MAPI, die WinInet-Klassen oder ISAPI verwenden.

Messaging API (MAPI)

Das beliebteste Netzwerk-Leistungsmerkmal ist in den meisten Büros die elektronische Post (E-Mail). Sie könnten Code in Ihre Anwendung aufnehmen, der über einen Socket die geeigneten Befehle generiert, um eine Mail-Nachricht zu übertragen, doch ist es wohl einfacher, auf die Arbeit anderer aufzusetzen.

Was ist MAPI?

MAPI (kurz für engl. Messaging Application Programing Interface) bietet eine Methode, Anwendungen, die Nachrichten senden und empfangen müssen (Messaging Applications), mit Anwendungen zu kombinieren, die wissen, wie Nachrichten gesendet und empfangen werden (Messaging Services und Service Provider). Dadurch wird die erforderliche Arbeit aller beteiligter Entwickler reduziert. In Abbildung 18.1 wird die Bandbreite des MAPI veranschaulicht. Beachten Sie, daß die Bezeichnung Messaging ein viel breiteres Spektrum abdeckt als nur das Versenden von E-Mails: Ein MAPI-Dienst kann etwa anstelle einer E-Mail auch ein Fax oder eine Voice-Mail-Nachricht senden. Wenn Ihre Anwendung die MAPI nutzt, werden die installierten Messaging-Dienste, z.B. E-Mail-Clients, das Senden der in Ihrer Anwendung erzeugten Nachrichten übernehmen.

Abbildung 18.1: Das Messaging-API deckt Anwendungen ab, die das Messaging-Merkmal benötigen, sowie Anwendungen, die es bereitstellen.

siehe Abbildung

Eine Anwendung kann das Messaging-Leistungsmerkmal in vielfacher Weise nutzen:

Anforderungen für das Win95-Logo

Der Hautgrund für einen Entwickler, seine Anwendung messaging-erkennend zu konzipieren, ist oft, den Anforderungen für das Messaging-Anwendungen fuer das Windows-95-LogoWindows 95-Logo entgegenzukommen. Um den Richtlinien für dieses Logo zu entsprechen, muß eine Anwendung im Menü Datei den Befehl Nachricht senden besitzen, der unter Verwendung des MAPI das Dokument versendet. (Ausnahmen werden für dokumentenlose Anwendungen gewährt.)

Wenn Sie dieses Leistungsmerkmal in Ihre Anwendungen aufnehmen wollen, sollten Sie am besten daran denken, bevor Sie mit Hilfe des Anwendungs-Assistenten das Anwendungsgerüst erstellen. Für alle, die vorausplanen, ist hier eine Liste der Aufgaben, die Sie erledigen müssen, um diesen Teil der Logo-Anforderungen zu erfüllen:

Das war's! Der Menübefehl wird automatisch ergänzt, und die Nachrichtentabellen und Nachrichtenbearbeitungsfunktionen werden generiert. Diese dienen zum Abfangen des Menübefehls und der Aufruffunktionen, die die Funktion Serialize Ihrer Anwendung benutzen, um das Dokument über das MAPI zu übertragen. In Abbildung 18.2 sehen Sie eine Anwendung mit dem Namen MAPIDemo, die auch auf der CD-ROM zu diesem Buch zu finden ist. Hierbei handelt es sich einfach um ein Programm, das vom Anwendungs-Assistenten generiert wird, wenn die MAPI-Option aktiviert wird.

Abbildung 18.2: Der Anwendungs-Assistent ergänzt das Menü Datei automatisch um den Befehl Nachricht senden und fügt den Code ein, der die Reaktion auf den Befehl regelt.

siehe Abbildung

Abgesehen von dem vom Anwendungs-Assistenten generierten Code brauchte für diese Anwendung kein Code geschrieben zu werden. Und wie Sie sehen, wurde in das Menü Datei der Befehl Nachricht senden aufgenommen. Wenn Sie diesen Menübefehl auswählen, wird Ihr MAPI-Mail-Client geladen, damit Sie die Nachricht versenden können. Die Abbildungen 18.2 und 18.3 stammen von einem System, bei dem Microsoft Exchange als Internet-Mail-Client installiert wurde. Es wird also Microsoft Exchange geladen (vgl. Abbildung 18.3). Die Nachricht umfaßt das aktuelle Dokument, und Sie brauchen nur noch Empfänger, Betreff und Text eingeben, der zusammen mit dem Dokument gesendet werden soll.

Abbildung 18.3: Microsoft Mail wird geladen, so daß der Anwender um das gesendete Dokument den Rest der E-Mail-Nachricht eintragen kann.

siehe Abbildung


Erscheint der Befehl Nachricht senden nicht in Ihrem Menü, überprüfen Sie, ob auf Ihrem System ein MAPI-Client installiert wurde. Microsoft Exchange ist ein leicht erhältlicher MAPI-Client. Die Funktion OnUpdateFileSendMail entfernt den Befehl Nachricht senden aus dem Menü, wenn auf Ihrem Rechner kein MAPI-Client registriert wurde.

Wenn Sie beim Erstellen der Anwendung im Anwendungs-Assistenten keine MAPI-Unterstützung angefordert haben, können Sie den Befehl Nachricht senden auch nachträglich hinzufügen. Dazu führen Sie folgende Arbeitsschritte aus:

Die Mail-Unterstützung manuell in eine Anwendung aufzunehmen, ist nicht viel schwieriger, als es vom Anwendungs-Assistenten ausführen zu lassen.

MAPI für Experten

Wenn Sie aus MAPI mehr herausholen wollen, als die Anforderungen für das Windows-Logo verlangen, wird die Sache schon etwas schwieriger. Im Prinzip gibt es vier Arten von MAPI-Client-Schnittstellen:

CMC: Das CMC-API verfügt nur über zehn Funktionen. Das macht das Erlernen einfacher, doch die Leistung reicht aus, um die wichtigsten Aufgaben zu erledigen. Diese Funktionen sind wie folgt:

Die Header-Datei XCMC.H deklariert eine Reihe von Strukturen für die Aufnahme der Informationen, die an diese Funktionen übergeben werden. Empfängerinformationen werden beispielsweise in der folgenden Struktur gespeichert:

/*RECIPIENT*/ 
typedef struct {
CMC_string name;
CMC_enum name_type;
CMC_string address;
CMC_enum role;
CMC_flags recip_flags;
CMC_extension FAR *recip_extensions;
} CMC_recipient;

Sie könnten diese Struktur mit dem Namen und der Adresse des Empfängers einer Mail-Nachricht ausfüllen, indem Sie ein Standarddialogfeld verwenden oder die Einträge wie folgt fest programmieren:

CMC_recipient recipient = { 
"Kate Gregory",
CMC_TYPE_INDIVIDUAL,
"SMTP:kate@gregcons.com",
CMC_ROLE_TO,
CMC_RECIP_LAST_ELEMENT,
NULL };

Type, Role und Flags verwenden einen der folgenden vordefinierten Werte:

Listing 18.1: Befehlsdefinitionen (Auszug aus der zu Visual C++ gehörenden Datei XCMC.H)

* NAME TYPES */ 
#define CMC_TYPE_UNKNOWN ((CMC_enum) 0)
#define CMC_TYPE_INDIVIDUAL ((CMC_enum) 1)
#define CMC_TYPE_GROUP ((CMC_enum) 2)
/* ROLES */
#define CMC_ROLE_TO ((CMC_enum) 0)
#define CMC_ROLE_CC ((CMC_enum) 1)
#define CMC_ROLE_BCC ((CMC_enum) 2)
#define CMC_ROLE_ORIGINATOR ((CMC_enum) 3)
#define CMC_ROLE_AUTHORIZING_USER ((CMC_enum) 4)
/* RECIPIENT FLAGS */
#define CMC_RECIP_IGNORE ((CMC_flags) 1)
#define CMC_RECIP_LIST_TRUNCATED ((CMC_flags) 2)
#define CMC_RECIP_LAST_ELEMENT ((CMC_flags) 0x80000000)

Es gibt eine Nachrichtenstruktur, die Sie auf dieselbe Weise ausfüllen könnten bzw. vom Anwender ausfüllen lassen, indem Sie diesem ein Dialogfeld mit den entsprechenden Nachrichteninformationen präsentieren. Diese Struktur enthält einen Zeiger auf die Empfängerstruktur, die Sie bereits ausgefüllt haben. Ihr Programm ruft dann cmc_logon, cmc_send und cmc_logoff auf, um den Vorgang abzuschießen.

Erweiterte MAPI: Das erweiterte MAPI basiert auf COM, dem Komponenten-Objekt-Modell. Nachrichten, Empfänger und viele andere Einheiten werden als Objekte (nicht Objekte im Sinn von C++) definiert. Es gibt viel mehr Objekttypen im erweiterten MAPI als Strukturtypen in den CMC. Zugang zu diesen Objekten erhalten Sie über OLE-(ActiveX-)Schnittstellen. Die Objekte stellen Eigenschaften, Methoden und Ereignisse bereit. Diese Konzepte werden in Teil V, Kapitel 14, »ActiveX-Konzepte«, erläutert.

Active-Messaging: Wenn Sie die Automation verstehen (vgl. Kapitel 16, »Einen Automations-Server entwickeln«) verstehen Sie auch schnell das Active-Messaging. Ihre Anwendung muß jedoch ein Automations-Client sein, und das Erstellen eines solchen Client liegt jenseits der Thematik dieses Kapitels. Einige Möglichkeitein für das Active-Messaging bestehen im Einsatz der Visual Basic-Programmierung und von VBA-Skripten für Programme wie Excel. Ihr Programm würde Objekte einrichten und dann ihre bereitgestellten Eigenschaften einstellen (z.B. die Zeile Betreff in einem Nachrichtenobjekt) und die bereitgestellten Methoden aufrufen (bei einem Nachrichtenobjekt etwa die Methode Send).

Folgende Objekte werden beim Active-Messaging verwendet:

Eine ausführliche Referenz dieser Objekte sowie ihrer Eigenschaften und Methoden finden Sie im Hilfesystem des Developer Studio.

Die WinInet-Klassen

Mit den MFC 4.2 wurde eine Reihe neuer Klassen vorgestellt, die das Erlernen der Socket-Programmierung unnötig machten, wenn die Anwendungen nur auf Standard-Internet-Client-Dienste zugreifen mußten. In Abbildung 18.4 sehen Sie, wie diese Klassen zusammenhängen. Diese unter dem Sammelbegriff WinInet-Klassen bekannten Klassen sind die Folgenden:

Abbildung 18.4: Die WinInet-Klassen erleichtern das Schreiben von Internet-Client-Programmen.

siehe Abbildung


Diese Klassen unterstützen Sie beim Schreiben von Internet-Client-Anwendungen, mit denen die Anwender direkt interagieren. Wenn Sie Server-Anwendungen schreiben möchten, die mit den Client-Anwendungen interagieren, sollten Sie sich für die ISAPI interessieren, die im nächsten Abschnitt behandelt wird.

Zunächst richtet Ihr Programm eine Sitzung ein, indem eine CInternetSession erstellt wird. Und wenn Sie die URL-Adresse Ressourcen abrufen ueber die Funk(Uniform Resource Locator) zu einer Gopher-, FTP- oder Web-(HTTP-)Ressource haben, können Sie die Funktion OpenURL dieser Sitzung aufrufen; dadurch wird die Ressource als CInternetFile im Lesemodus abgerufen. Ihre Anwendung kann die Datei mit Hilfe von CStdioFile-Funktionen lesen und diese Daten in der gewünschten Weise manipulieren.

Wenn Sie die URL nicht kennen oder eine Datei nicht nur im Lesemodus abrufen wollen, ist das weitere Vorgehen nach dem Sitzungsaufbau unterschiedlich. Sie stellen die Verbindung mit einem spezifischen Protokoll her, indem Sie die Funktionen GetFtpConnection, GetGopherConnection oder GetHttpConnection dieser Sitzung aufrufen, die das entsprechende Verbindungsobjekt liefern. Dann rufen Sie die Funktion OpenFile der Verbindung auf. CFtpConnection::OpenFile liefert eine CInternetFile; CGopherConnection::OpenFile liefert eine CGopherFile und CHttpConnection::OpenFile liefert eine CHttpFile. Die Klasse CFileFind und die von ihr abgeleiteten Klassen helfen beim Auffinden der zu öffnenden Datei.

Kapitel 19, »Internet-Programmierung mit den WinInet-Klassen«, stellt ein Beispiel-Client-Programm vor, das mit Hilfe der WinInet-Klassen eine Internet-Sitzung aufbaut und Informationen abruft.


Obwohl E-Mail eine Standard-Internet-Anwendung ist, werden Sie feststellen, daß die WinInet-Klassen keine E-Mail-Funktionalität besitzen. Das liegt daran, daß E-Mail von der MAPI verarbeitet wird. Auch Usenet-News werden nicht unterstützt, weder durch die WinInet-Klassen noch durch andere Klassen.

Klassen des Internet-Server-API (ISAPI)

Mit Hilfe von ISAPI lassen sich die Fähigkeiten Ihres HTTP-Servers (WWW-Servers) verbessern und erweitern. ISAPI-Entwickler erstellen Erweiterungen und Filter. Erweiterungen sind DLLs, die vom Anwender von einer Web-Seite aus aufgerufen werden, in ähnlicher Weise wie CGI-Anwendungen von Web-Seiten aus aufgerufen werden. Filter sind DLLs, die mit dem Server zusammen ausgeführt werden und die ein- und ausgehenden Daten beobachten oder ändern. Beispielsweise kann ein Filter Anfragen für eine Datei zu einer neuen Web-Adresse umleiten.

Damit die von Ihnen programmierten ISAPI-Erweiterungen und -Filter auch praktisch einsetzbar sind, müssen Ihre Web-Seiten auf einem ISAPI-konformen Server, wie etwa dem Microsoft IIS Server, gespeichert sein. Zudem müssen Sie die geeigneten Rechte besitzen, um DLLs auf diesem Server installieren zu dürfen, und für ISAPI-Filter müssen Sie die Möglichkeit haben, die Registrierung auf dem Server zu ändern. Sind Ihre Web-Seiten auf einem Rechner gespeichert, der von Ihrem Internet Service Provider (ISP) verwaltet wird, so werden Sie vermutlich nicht in der Lage sein, ISAPI zur Verbesserung Ihrer Web-Seiten einzusetzen. Eine Möglichkeit wäre, Ihre Seiten auf einen konformen Server zu verlagern (ein leistungsstarker Intel-Rechner, auf der Windows NT Server 4.0 und Microsoft IIS ausgeführt werden, wäre eine gute Wahl), damit Sie ISAPI verwenden können. Doch ist diese Möglichkeit auch mit beträchtlichen Ausgaben verbunden. Informieren Sie sich auf jeden Fall über die Einschränkungen Ihres aktuellen Web-Servers, bevor Sie versuchen, ein Projekt mit Hilfe von ISAPI zu realisieren.

Die folgenden fünf MFC-ISAPI-Klassen bilden einen Wrapper für das API:

Ihre Anwendung wird eine Server- oder Filterklasse (oder beides) besitzen, die von CHttpServer bzw. CHttpFilter abgeleitet ist. Beide gleichen den Klassen in einer normalen Anwendung, die von CWinApp abgeleitet sind. In jeder DLL gibt es nur eine Instanz der Klasse, und jede Interaktion des Server mit einem Client geschieht durch seine eigene Instanz der entsprechenden Kontextklasse. (Eine DLL kann sowohl einen Server als auch einen Filter enthalten, doch jeweils höchstens einen.) CHtmlStream ist eine Hilfsklasse, die einen HTML-Strom beschreibt, der von einem Server zu einem Client gesendet wird.

Der ISAPI-Erweiterung Wizard ist ein Anwendungs-Assistent, der Sie beim Erstellen von Erweiterungen und Filtern unterstützt. Um diesen Assistenten einzusetzen, wählen Sie wie immer im Developer Studio Datei/Neu, und öffnen das Register Projekte. Markieren Sie den Listeneintrag Assistent für ISAPI-Erweiterungen (siehe Abbildung 18.5), tragen Sie den Projektnamen und Ordner ein, und klicken Sie auf OK.

Abbildung 18.5: Der Assistent für ISAPI-Erweiterungen dient zum Erstellen von Erweiterungen und Filtern.

siehe Abbildung

Das Erstellen einer Server-Erweiterung erfordert nur einen Arbeitsschritt. Die zugehörige Eigenschaftsseite (die auch mit dem ersten Schritt für die Erstellung eines Filters übereinstimmt) sehen Sie in Abbildung 18.6. Die Namen und Beschreibungen für die Filter und Erweiterungen basieren auf dem angegebenen Projektnamen.

Abbildung 18.6: Im ersten Schritt des Assistenten für ISAPI-Erweiterungen geben Sie die Namen der Komponenten der zu erstellenden DLL an.

siehe Abbildung

Wenn Sie sich für das Erstellen eines Filters entscheiden, wird die Schaltfläche Weiter aktiviert, so daß Sie die zweite Seite für Erstellung von Filtern aufschlagen können (siehe Abbildung 18.7). Allein diese Parameterliste verschafft Ihnen einen Eindruck von der Leistungsvielfalt eines ISAPI-Filters. Sie können alle ein- und ausgehenden Anfragen und unformatierten Daten, die Zugangsberechtigung eines Anwenders (Echtheitsbestätigung) sowie Eintragungen in das Server-Protokoll überwachen lassen.

Abbildung 18.7: Im ersten Schritt des Assistenten für ISAPI-Erweiterungen können Sie die Eigenschaften des Filters bestimmen.

siehe Abbildung

Bevor die Dateien erzeugt werden, wird noch einmal eine Zusammenfassung eingeblendet, die Sie bestätigen müssen. Wenn Sie einen Server und einen Filter gleichzeitig anlegen, werden elf Dateien erzeugt, einschließlich der Quelldateien für die Klassen, die von CHttpServer und CHttpFilter abgeleitet wurden.

Das Programmieren eines Filters auf der Grundlage dieses Gerüsts ist recht einfach. Ihr Programm wurde mit einem Funktionsgerüst ausgestattet, damit es auf jedes Ereignis reagieren kann, für das eine Benachrichtigung angefordert wurde. Die Filterklasse besitzt beispielsweise die Funktion OnEndOfNetSession, die aufgerufen wird, wenn eine Client-Sitzung mit diesem Server beendet wird. In diese Funktion fügen Sie den Code zum Protokollieren, Überwachen oder sonstigen Reagieren auf dieses Ereignis ein. Ist der Filter fertig, so ändern Sie die Registrierung manuell so ab, daß der Server Ihre DLL ausführt.

Um eine Erweiterung zu programmieren, fügen Sie eine oder mehrere Funktionen in Ihre DLL ein. An jede Funktion wird ein CHttpContext-Zeiger übergeben, der zum Sammeln von Informationen, wie etwa der IP-Adresse des Anwenders, verwendet werden kann. Wird die Funktion von einem HTML-Formular aus aufgerufen, werden weitere Parameter, etwa die Werte aus anderen Feldern in dem Formular, an die Funktion übergeben.

Was diese Funktion nun genau macht, hängt von Ihrer Anwendung ab. Angenommen, Sie implementieren ein Online-Bestellsystem, so sind umfangreiche und komplexe Funktionen erforderlich. Andere Erweiterungen wiederum sind einfacher.

Ist Ihre Funktion fertig programmiert, plazieren Sie die DLL in dem ausführbaren Ordner Ihres Servers û in der Regel der Ordner, in dem auch CGI-Programme gespeichert werden û und fügen folgende Links in Ihre Web-Seiten ein, wenn die Erweiterung aufgerufen werden soll:

Hier können Sie <A HREF=http://www.company.com/exec/orders.dll> Ihre Bestellung </A> aufgeben!

Wie geht's weiter?

Die Miteinbeziehung des Internet in Ihre Anwendungen ist ein aufregender Trend. Für die Programmier bedeutet es viel Arbeit bei der Entwicklung leistungsfähiger Produkte, die allen Internet-Anwendern das Arbeitsleben erleichtern. Noch vor nur einem Jahr bedeutete die Programmierung von Internet-Anwendungen Ärmel hochkrempeln und Sockets-Zugänge programmieren, TCP/IP-Ports memorieren und RFCs lesen. Die neuen WinInet- und ISAPI-Klassen sowie Verbesserungen der alten MAPI-Unterstützung bedeuten für Sie, daß Sie durch wenige Zeilen Programmcode oder die Auswahl einer Option in einem Assistenten-Dialogfeld Ihre Anwendungen durch eine erstaunliche Leistungsvielfalt bereichern können.

Mehr über den Einsatz der in diesem Kapitel vorgestellten APIs und über das Erstellen anderer, spezifischer Anwendungen erfahren Sie in den folgenden Kapiteln:


© 1997 Que
Ein Imprint des Markt&Technik Buch- und Software- Verlag GmbH
Elektronische Fassung des Titels: Special Edition Visual C++ 5.0, ISBN: 3-8272-1019-4

Previous Page Page Top TOC Index Next Page See Page