CONZEPT 16 bietet bereits eine Vielzahl an Schnittstellen um Ihrer Applikation den Dialog mit anderer Software zu ermöglichen. Sollten Sie dennoch einmal eine Schnittstelle vermissen, haben Sie häufig die Möglichkeit sie mit den Bordmitteln von CONZEPT 16 zu realisieren.
Am Beispiel des Post Office Protcol (POP), zum Abfragen und Abholen von E-Mails bei einem E-Mail-Server, stelle ich hier die Implementierung eines einfachen Protokolls vor.
Das POP ist – wie die meisten Internet-Protokolle – ein Text-orientiertes Protokoll. Dies bedeutet, die ausgetauschten Informationen sind größtenteils Menschen-lesbar. Es basiert auf dem TCP/IP-Protokoll für das CONZEPT 16 die Socket-Funktionen nativ bereitstellt. Aufbauend auf diesen Funktionen lässt sich dieses Protkoll mit geringem Aufwand realisieren.
Das Protokoll
Das Protokoll spezifiziert eine Reihe von Kommandos, die vom Client an den Server übertragen und von diesem beantwortet werden.
Zum Abfragen und Abholen von Nachrichten sind unter anderem folgende Kommandos verfügbar:
- USER <username>
Wählt den Benutzer zur Anmeldung. - PASS <password>
Übergibt das Passwort zur Anmeldung. - STAT
Liefert den Status des E-Mail-Kontos, das heißt die Anzahl der darin enthaltenen Nachrichten und deren Größe. - RETR <message-no>
Holt eine Nachricht ab ohne sie zu löschen. - TOP <message-no> <body-lines>
Wie RETR, jedoch werden nur die angegebene Anzahl Zeilen übertragen. Wird nicht von jedem Server unterstützt. - DELE <message-no>
Löscht eine Nachricht. - QUIT
Beendet die Sitzung.
Der Server kann auf ein Kommando mit zwei verschiedenen Resultaten antworten:
- +OK [<response>]
Das Kommando wurde erfolgreich durchgeführt. Bei einigen Kommandos wird auch eine Antwort übertragen. - -ERR [<error-text>]
Bei der Durchführung des Kommandos ist ein Fehler aufgetreten. Ein Fehlertext kann ebenfalls vom Server übertragen werden.
Die Implementierung
In diesem Beispiel ist das Protokoll in einer Prozedur – nach dem Prinzip der Modularen Programmierung – implementiert. Die Prozedur können Sie am Ende des Artikels herunterladen. Das Modul verfügt über folgende Schnittstellenfunktionen:
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// + Verbindung herstellen und anmelden +
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
sub POP.Init
(
aHost : alpha; // Server
aPort : word; // Port (Standardport: 110)
aUser : alpha; // Benutzer
aPass : alpha; // Passwort
opt aTextLog : handle; // Protokolltext
)
: int; // Fehler
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// + Abmelden und Verbindung trennen +
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
sub POP.Term();
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// + Status und Nachrichten abfragen +
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
sub POP.Check
(
var vCount : int; // Anzahl Nachrichten
var vSize : int; // Größe aller Nachrichten
opt aCteNodeMsgs : handle; // Liste aller Nachrichten
)
: int; // Fehler
Die Verwendung
Mit der Funktion POP.Init()
wird das Modul initialisiert, eine Verbindung zum E-Mail-Server hergestellt und die Anmeldung an einem E-Mail-Konto durchgeführt. Anschließend kann mit der Funktion POP.Check()
die Anzahl der Nachrichten, deren Größe und deren Kopfinformationen – wie Betreff, Abwesender und Empfänger – ermittelt werden. Die Funktion POP.Term()
führt schließlich die Abmeldung und den Verbindungsabbau durch:
// Verbindung herstellen und anmelden
tErr # POP.Init('myServer', 110, 'myUser', 'myPassword');
if (tErr = _ErrOK)
{
tCteNodeMsgs # CteOpen(_CteNode, _CteChildList);
// Status und Nachrichten abfragen
tErr # POP.Check(var tCount, var tSize, tCteNodeMsgs);
// Abmelden und Verbindung trennen
POP.Term();
if (tErr = _ErrOK and tCount > 0)
{
for tCteNodeMsg # tCteNodeMsgs->CteRead(
_CteChildList | _CteFirst);
loop tCteNodeMsg # tCteNodeMsgs->CteRead(
_CteChildList | _CteNext, tCteNodeMsg);
while (tCteNodeMsg > 0)
{
// Betreff ermitteln
tCteNodeMsgHeader # tCteNodeMsg->CteRead(
_CteAttribTree | _CteCmpE, 0, 'Subject');
if (tCteNodeMsgHeader > 0)
tStrSubject # tCteNodeMsgHeader->spValueAlpha;
// Absender ermitteln
tCteNodeMsgHeader # tCteNodeMsg->CteRead(
_CteAttribTree | _CteCmpE, 0, 'From');
if (tCteNodeMsgHeader > 0)
tStrFrom # tCteNodeMsgHeader->spValueAlpha;
// ...
}
}
tCteNodeMsgs->CteClear(true);
tCteNodeMsgs->CteClose();
}
Die Kommunikation
Die dabei entstandene Kommunikation könnte zum Beispiel so aussehen:
Begrüßung empfangen
< +OK Server ready <123456789@myServer>
Benutzer senden
> USER myUser
< +OK myUser try a password
Passwort senden
> PASS myPassword
< +OK mailbox ready
Status abfragen
> STAT
< +OK 1 4654
Nachricht abfragen
> TOP 1 0
< +OK
Received: from myComputer; Mon, 14 May 2012 15:14:18 +0200
Message-ID: <0102030405060708090A0B0C0D0E0F@myServer>
From: "Emil A. D. Resse" <>
To: <>
Subject: Hallo vectorsoft-Team
Date: Mon, 14 May 2012 16:14:18 +0200
Importance: normal
Priority: normal
.
Abmelden
> QUIT
Fazit
Mit der Socket-Schnittstelle haben Sie die Möglichkeit die Konnektivität Ihrer Anwendung zu erhöhen. Durch die Implementierung TCP/IP-basierter Protokolle können Sie Schnittstellen einfach nachrüsten, falls CONZEPT 16 dieses nicht von Haus aus mitbringt. Neben dem Post Office Protocol, ist beispielsweise auch eine Implementierung des darauf aufbauenden Internet Message Access Protocol (IMAP) denkbar.
2 Antworten
Ja, wenn die Schnittstelle nicht hinreichend dokumentiert ist oder Inkompatibilitäten zwischen verschiedenen Versionen bestehen ist das ein Problem. Da hilft wohl nur die Abfrage/Überprüfung der Version und detailliertes Testen der Implementierung.
Die Herausforderung bei solchen Schnittstellen sind die (natürlich nicht dokumentierten) Eigenwilligkeiten (z.B. bei Outlook "Eigenschaft ungültig") und Versionssprünge