Galileo Computing < openbook >
Galileo Computing - Professionelle Buecher. Auch fuer Einsteiger.
Galileo Computing - Professionelle Buecher. Auch fuer Einsteiger.


Java ist auch eine Insel von Christian Ullenboom
Buch: Java ist auch eine Insel (Galileo Computing)
gp Kapitel 16 Netzwerkprogrammierung
gp 16.1 Grundlegende Begriffe
gp 16.1.1 Internet-Standards und RFC
gp 16.2 URL-Verbindungen und URL-Objekte
gp 16.2.1 Die Klasse URL
gp 16.2.2 Informationen über eine URL
gp 16.2.3 Der Zugriff auf die Daten über die Klasse URL
gp 16.2.4 Verbindungen durch einen Proxy-Server
gp 16.3 Die Klasse URLConnection
gp 16.3.1 Methoden und Anwendung von URLConnection
gp 16.3.2 Protokoll- und Content-Handler
gp 16.3.3 Im Detail: vom URL zu URLConnection
gp 16.3.4 Autorisierte URL-Verbindungen mit Basic Authentication
gp 16.3.5 Apache Jakarta HttpClient
gp 16.4 Das Common Gateway Interface
gp 16.4.1 Parameter für ein CGI-Programm
gp 16.4.2 Kodieren der Parameter für CGI-Programme
gp 16.4.3 Eine Suchmaschine ansprechen
gp 16.5 Host- und IP-Adressen
gp 16.5.1 Das Netz ist Klasse ...
gp 16.5.2 IP-Adresse des lokalen Hosts
gp 16.5.3 Die Methode getAllByName()
gp 16.6 NetworkInterface
gp 16.7 IPv6 für Java mit Jipsy
gp 16.8 Socket-Programmierung
gp 16.8.1 Das Netzwerk ist der Computer
gp 16.8.2 Standarddienste unter Windows nachinstallieren
gp 16.8.3 Stream-Sockets
gp 16.8.4 Informationen über den Socket
gp 16.8.5 Mit telnet an den Ports horchen
gp 16.8.6 Ein kleines Echo - lebt der Rechner noch?
gp 16.9 Client/Server-Kommunikation
gp 16.9.1 Warten auf Verbindungen
gp 16.9.2 Ein Multiplikations-Server
gp 16.10 SLL-Verbindungen mit JSSE
gp 16.11 Web-Protokolle mit NetComponents nutzen
gp 16.12 E-Mail
gp 16.12.1 Wie eine E-Mail um die Welt geht
gp 16.12.2 Übertragungsprotokolle
gp 16.12.3 Das Simple Mail Transfer Protocol
gp 16.12.4 E-Mails versenden mit Suns JavaMail-API
gp 16.12.5 MimeMultipart-Nachrichten schicken
gp 16.12.6 E-Mails mittels POP3 abrufen
gp 16.13 Arbeitsweise eines Web-Servers
gp 16.13.1 Das Hypertext Transfer Protocol (HTTP)
gp 16.13.2 Anfragen an den Server
gp 16.13.3 Die Antworten vom Server
gp 16.14 Datagram-Sockets
gp 16.14.1 Die Klasse DatagramSocket
gp 16.14.2 Datagramme und die Klasse DatagramPacket
gp 16.14.3 Auf ein hereinkommendes Paket warten
gp 16.14.4 Ein Paket zum Senden vorbereiten
gp 16.14.5 Methoden der Klasse DatagramPacket
gp 16.14.6 Das Paket senden
gp 16.14.7 Die Zeitdienste und ein eigener Server und Client
gp 16.15 Internet Control Message Protocol (ICMP)
gp 16.15.1 Ping
gp 16.16 Multicast-Kommunikation


Galileo Computing

16.12 E-Maildowntop

E-Mail ist heute ein wichtiger Teil der modernen Kommunikation. Die Vorteile bei der Technik sind vielfältig: Das Medium ist schnell, die Nachrichtenübertragung ist asynchron und die Informationen können direkt weiterverarbeitet werden: ein Vorteil, der bei herkömmlichen Briefen nicht gegeben ist.


Galileo Computing

16.12.1 Wie eine E-Mail um die Welt gehtdowntop

In einem E-Mail-System kommen mehrere Komponenten vor, die kurz benannt werden sollen:

gp User
Der Benutzer des Mail-Systems, der Nachrichten verschickt oder empfängt
gp Mail User Agent (MUA)
Die Schnittstelle zwischen dem Benutzer und dem Mail-System
gp Message Store (MS)
Dient dem Mail User Agent zum Ablegen der Nachrichten.
gp Message Transfer Agent (MTA)
Dies sind Komponenten des Message Transfer Systems und verantwortlich für die eigentliche Nachrichtenübermittlung.
gp Message Transfer System (MTS)
Ist die Gesamtheit der Message Transfer Agents und ihrer Verbindungen.

Die Nachrichtenübermittlung läuft also über diese Komponenten, wobei der Benutzer durch sein Mail User Agent (MUA) die Nachricht erstellt. Anschließend wird diese Nachricht vom MUA an den Message Transfer Agent übergeben. Nun ist es Aufgabe dieser Agenten, entweder direkt (der Empfänger ist im gleichen Netzwerk wie der Sender) oder über Store-and-Forward die Botschaft zu übermitteln. Danach ist der Sender aus dem Spiel, und der Empfänger nimmt die E-Mail entgegen. Sie wird vom Ziel-MTA an den Mail-User-Agenten des Abrufenden geholt.


Galileo Computing

16.12.2 Übertragungsprotokolledowntop

Für die Übertragung von E-Mail haben sich zwei Protokolle etabliert: X.400 und SMTP. Während SMTP breite Akzeptanz besitzt und es viele Implementierungen und Benutzungsoberflächen gibt, ist X.400 kommerziell gefälliger. Es ist in Standardisierungsgremien anerkannt und bietet Möglichkeiten, die über SMTP hinausgehen. Diese Dienste werden für SMTP erst durch neue Spezifikationen wie MIME möglich.

Das Simple Mail Transfer Protocol und RFC 822

Das Simple Mail Transfer Protocol (kurz SMTP) ist ein Versende-Protokoll, welches im RFC 2821 beschrieben ist. Zusammen mit dem RFC 822 (Standard for the Format of ARPA Internet Text Messages), welches den Austausch von textbasierten Nachrichten im Internet beschreibt, bildet dies das Gerüst des Mail-Systems. Über RFC 822 wird nur der Aufbau der Nachrichten beschrieben - es ist kein Protokoll - und im RFC 2821 das Protokoll zum Verschicken und Übertragen der Nachrichten von einem Rechner zum anderen beschrieben. Beide Systeme sind schon recht alt, das Simple Mail Transfer Protocol stammt ebenso wie der Standard für die ARPA-Internet-Text-Nachrichten aus dem Jahr 1982. Was früher noch genügte, wird heute immer mehr zum Hindernis, da die kommerzielle (böse) Welt ganz andere Weichen stellt.

SMTP verwendet den Standard RFC 822 zur Schreibweise der E-Mail-Adressen. Diese Adressierung verwendet den Rechnernamen (beziehungsweise Netznamen) des Adressaten. Mit dem leicht zu merkenden Fully Qualified Host Name (kurz FQHN) lassen sich die E-Mails leicht verteilen. Denn jeder Rechner ist im DNS aufgeführt, und wenn der Name bekannt ist, lässt es sich leicht zum Empfänger routen. So macht es zum Beispiel das Programm sendmail. Es baut eine direkte Verbindung zum Zielrechner auf und legt die Nachricht dort ab. Da allerdings gerne eine Unabhängigkeit von real existierenden Rechnern erreicht werden soll, werden in der Regel MX-Records (Mail Exchanger Resource Records) eingesetzt. Dann tritt ein anderer Rechner als Mail Transfer Agent auf, und so ist Erreichbarkeit für die Rechner gewährleistet, die nicht am Internet angeschlossen sind. Außerdem können auch mehrere Rechner als MTAs definiert werden, um die Ausfallsicherheit zu erhöhen. Zudem haben MX-Records den Vorteil, dass auch (einfachere) E-Mail-Adressen formuliert werden können, für die es keinen Rechner gibt.

Die Einteilung der Domains erfolgt in organisatorische Toplevel-Domains. Einige sind:


Domain-Endung Bedeutung
.biz Business
.com Kommerzielle Organisation
.edu Bildungseinrichtung
.firm Firma
.gov US-Regierung und Staatsapparat
.net Netzwerkunterstützende Organisation
.mil US-Militärische Organisationen
.org Internationale nicht kommerzielle Organisation

Über die Erweiterung dieser Toplevel-Domains gibt es immer wieder Ärger. Hier streiten sich die amerikanische Regierung und die Anbieter. Ohnehin ist dies alles eine ziemlich amerikanische Angelegenheit. In Planung sind ebenfalls .coop (Genossenschaften), .aero (Luftfahrt), .museum (Museen), .name (Namen, Privatpersonen), .pro (Berufsgruppen) und .eu (Europa). Für jedes Land gibt es dann noch einmal eine Sonderendung, wie das .de für Deutschland.

Im RFC 822 sind zwei von Grund auf unterschiedliche Adressierungsarten beschrieben. Allerdings wird nur eine davon offiziell unterstützt, und zwar die Route-Adressierung. Dies ist eine Liste von Domains, über die die E-Mail verschickt werden soll. Der Pfad des elektronischen Postmännchens wird also hier im Groben vorgegeben. Die zweite Adressierung ist die Local-Part-Adressierung. Hier wird ein spezieller Rechner angesprochen.

Multipurpose Internet Mail Extensions (MIME)

Als das Internet in den Anfängen war, bestand eine E-Mail meistens aus lesbaren englischen Textnachrichten. Wenn denn einmal binäre Dateien verschickt werden sollten, so mussten diese vom Benutzer unter Unix mit einem uuencode in 7-Bit-ASCII umgewandelt und dann verschickt werden. Der Standard des RFC 822 kann viele der heute anzutreffenden Daten nicht kodieren:

gp Binärdaten (zum Beispiel Audiodaten, Bilder, Video, Datenbanken)
gp Nachrichten in Sprachen mit Umlauten und Akzenten (Deutsch, Französisch)
gp Nachrichten in nicht lateinischen Sprachen (Hebräisch, Russisch) oder sogar Sprachen ohne klassisches Alphabet (Chinesisch, Japanisch)

Um Abhilfe zu schaffen, wurde MIME im RFC 1341 und RFC 1521 vorgeschlagen. Um ASCII-fremde Nachrichten zu kodieren, werden fünf Nachrichten-Header definiert und die Binärdateien nach base64-Encoding umgesetzt. Für Nachrichten, die fast nur aus ASCII-Zeichen bestehen, wäre dies aber zu großer Overhead, so dass Quoted Printing Encoding eingesetzt wird. Dies definiert lediglich alle Zeichen über 127 durch zwei hexadezimale Zeichen. Dieses Kodierungsverfahren entdecken wir oft in URLs, welche von Formularen erzeugt werden, etwa http://www.google.de/search?q=r%FCssel.

X.400

Die ISO und CCITT haben X.400 auf die Beine gestellt. Es ist ein Kurzname für eine Reihe von Standards, die im Gegensatz zum proprietären RFC offiziell verabschiedet sind. Die Entwicklung von X.400 ist in Studienperioden von jeweils vier Jahren eingeteilt. Es soll einen Gegenpol zum Quasistandard schaffen, was auch durch die Unterstützung der Telekommunikationsgesellschaften unterstrichen wird. Bisher konnte sich X.400 jedoch nicht durchsetzen (und es sieht auch zukünftig nicht so aus). Erschwerend kommt hinzu, dass die X.400-Standards nicht kostenfrei zu bekommen sind.

Die Schreibweise einer X.400-Adresse unterscheidet sich schon rein optisch von der Angabe des RFC 822. Hier wird eine Attributschreibweise (auch O/R-Adresse) verwendet, die eine Reihe von Attributen (sprich Attributtyp und -wert) angibt. Die Einteilung der Adressen erfolgt auf oberster Ebene in Länder und in der nächsten Stufe in administrative Bereiche. Dies kann zum Beispiel eine Telefongesellschaft sein.

Das System der Zukunft

Das heute noch vielfach eingesetzte SMTP bereitet den Anwendern viele Sorgen. So müssen sie sich mit dem Versand von gefälschten E-Mails herumschlagen (Mail-Spoofing), zudem ist unerbetene kommerzielle Werbung (Unsolicited Commercial E-Mail, kurz UCE) und UBE (Unsolicited Bulk E-Mail), besser bekannt als Spam, ein wirtschaftlich negativer Faktor. Das Ursprungs-SMTP wird mit diesen Problemen nicht fertig, da der Einsatz für ein überschaubares Netz gedacht war, dessen Teilnehmer sich kennen. Viele SMTP-Server sind so brav, dass sie eine E-Mail von jedem beliebigen Absender zu jedem beliebigen Adressaten schicken. Auch andere Probleme sind noch nicht gelöst. Dazu gehören zum Beispiel eine Einlieferungsbestätigung (Proof of Submission). Zwar lässt sendmail das Senden von Empfangsbestätigungen mit einem speziellen Return-Receipt-To-Feld zu, doch dieses ist bisher nicht offiziell im RFC 822 standardisiert.


Galileo Computing

16.12.3 Das Simple Mail Transfer Protocoldowntop

Die Idee eines E-Mail-Programms ist einfach: Zunächst muss eine Verbindung zum richtigen E-Mail-Server stehen, und anschließend kann die Kommunikation mit ein paar Kommandos geregelt werden. Mit dieser Technik kann dann eine Mail empfangen und gesendet werden. Nun besteht das E-Mail-System aber aus zwei Teilen: zum einen aus dem Empfänger und zum anderen aus dem Sender. Die empfangende Seite setzt auf das POP3-Protokoll, die sendende Seite auf SMTP oder IMAP. POP3 ist die dritte Version des Post Office Protocol. Der POP3-Server sitzt auf der Empfängerseite und stellt die Infrastruktur bereit, damit die E-Mail eingesehen werden kann.1 Beide Systeme arbeiten also Hand in Hand. Wird mittels SMTP-Server eine E-Mail versendet, so kann sie durch den POP3-Server abgerufen werden.


Galileo Computing

16.12.4 E-Mails versenden mit Suns JavaMail-APIdowntop

Nachdem wir alles mehr theoretisch betrachtet haben, soll nun ein kleines Programm folgen, mit dem sich eine E-Mail abschicken lässt. Das Programm ist bewusst klein. Es nutzt die JavaMail-API, eine eigene Bibliothek, die zum Versenden und Empfangen von E-Mail entworfen wurde. Sie lässt sich von http://java.sun.com/products/javamail/ beziehen. Zudem muss das Archiv activation.jar mit im Klassenpfad aufgenommen werden. Bei Enterprise-Applikationen sind die Archive Bestandteil einer J2EE-Installation.

Listing 16.16 SendJavaMail.java

package javamail;
import java.util.*;
import javax.mail.*;
import javax.mail.internet.*;
public class SendJavaMail
{
  public static void postMail( String recipient,
                               String subject,
                               String message, String from )
    throws MessagingException
  {
    Properties props = new Properties();
    props.put( "mail.smtp.host", "mail.java-tutor.com" );
    
    Session session = Session.getDefaultInstance( props );
    
    Message msg = new MimeMessage( session );
    
    InternetAddress addressFrom = new InternetAddress( from );
    msg.setFrom( addressFrom );
    
    InternetAddress addressTo = new InternetAddress( recipient );
    msg.setRecipient( Message.RecipientType.TO, addressTo );
    
    msg.setSubject( subject );
    msg.setContent( message, "text/plain" );
    Transport.send( msg );
  }
  
  public static void main( String args[] ) throws Exception
  {
    postMail( "Buchtest@java-tutor.com",
              "Tolles Buch",
              "Wow. Das Buch ist schön zu lesen",
              "JavaTutor@java-tutor.com");
  }
}

An dem Beispiel ist abzulesen, dass der Empfänger (Buchtest@java-tutor.com) eine Nachricht von JavaTutor@java-tutor.com bekommt. Das Subjekt ist »Tolles Buch«, und der dritte Parameter gibt den Inhalt der E-Mail an.


Galileo Computing

16.12.5 MimeMultipart-Nachrichten schickendowntop

Neben den klassischen MIME-Typen application, audio, image, message und video zur Beschreibung der Datentypen einer E-Mail dient der Typ multipart dazu, in einer E-Mail mehrere Teile mit (in der Regel) unterschiedlichen MIME-Teile zu kodieren. Die JavaMail-API bietet für diesen Fall die Klasse MimeMultipart an; eine Containerklasse, der mit addBodyPart() diverse MimeBodyPart-Objekte hinzugefügt werden können. Zum Schluss - sind die Köper aufgebaut - setzt auf dem Message-Objekt setContent() nun nicht mehr das einfache MimeMessage-Objekt mit einem expliziten MIME-Typ, sondern das MimeMultipart-Objekt.

Das nachfolgende Beispiel zeigt ein Message-Objekt mit zwei Teilen. Einmal eine normale text/plain-Nachricht und zum anderen eine text/html-Nachricht. Der Konstruktor eines MimeMultipart-Objekts gibt der mehrtyp-Nachricht einen Namen. Ist dieser mit dem String »alternative«, so heißt das für den Mail-Client, dass es verschiedene Versionen desselben Textes enthält. Standardmäßig versendet so zum Beispiel Microsoft Outlook die E-Mails. Sie werden als reiner Text und als HTML verschickt.

MimeMultipart content = new MimeMultipart( "alternative" );
MimeBodyPart text = new MimeBodyPart();
MimeBodyPart html = new MimeBodyPart();
text.setText( "Text als normaler String" );
text.setHeader( "MIME-Version" , "1.0" );
text.setHeader( "Content-Type" , text.getContentType() );
html.setContent( "<html>Text als <b>HTML</b></html>", "text/html");
html.setHeader( "MIME-Version" , "1.0" );
html.setHeader( "Content-Type" , html.getContentType() );
content.addBodyPart( text );
content.addBodyPart( html );
Message msg = ...
msg.setContent( content );
msg.setHeader( "MIME-Version" , "1.0" );
msg.setHeader( "Content-Type" , content.getContentType() );
msg.setHeader( "X-Mailer", "Java-Mailer V 1.0234.23455345" );
msg.setSentDate( new Date() );

Galileo Computing

16.12.6 E-Mails mittels POP3 abrufentoptop

Die andere Seite soll ebenso betrachtet werden. Sie ist ein klein wenig aufwändiger, da die Nachrichten (Messages) erst dekodiert werden müssen. Dennoch geht die Arbeitsweise leicht aus dem Programm hervor.

Listing 16.17 SendJavaMail.java

package javamail;
import java.util.*;
import java.io.*;
import javax.mail.*;
import javax.mail.internet.*;
public class GetEMails
{
  public static void getMail( String host, String user, String passwd )
    throws Exception
  {
    Session session = Session.getDefaultInstance( new Properties() );
    
    Store store = session.getStore( "pop3" );
    store.connect( host, user, passwd );
    
    Folder folder = store.getFolder( "INBOX" );
    folder.open( Folder.READ_ONLY );
    
    Message message[] = folder.getMessages();
    
    for ( int i = 0; i < message.length; i++ )
    {
      Message m = message[i];
      
      System.out.println( "Nachricht: " + i );
      System.out.println( "From: " + m.getFrom()[0] );
      System.out.println( "Subject: " + m.getSubject() );
      
      Multipart mp = (Multipart)m.getContent();
      
      for ( int j = 0; j < mp.getCount(); j++ )
      {
        Part part = mp.getBodyPart( j );
        
        String disposition = part.getDisposition();
        
        if ( disposition == null )
        {
          MimeBodyPart mimePart = (MimeBodyPart)part;
          
          if ( mimePart.isMimeType("text/plain") )
          {
            BufferedReader in = new BufferedReader(
              new InputStreamReader(mimePart.getInputStream()) );
            
            String line;
            while ( (line=in.readLine()) != null )
              System.out.println( line );
          }
        }
      }
    }
    folder.close( false );
    store.close();
  }
  
  public static void main( String args[] ) throws Exception
  {
    getMail( "pop.t-online.de",
             "12345678-0001@t-online.de", "passwd" );
  }
}

Das Programm listet alle E-Mails vom Server auf und schreibt die Inhalte auf den Bildschirm. Die Nachrichten werden aber nicht vom Server gelöscht. In dem oberen Beispiel ist das Passwort natürlich anzupassen.


Beispiel Um herauszufinden, ob überhaupt Nachrichten auf dem Server liegen, lässt sich auf dem aktuellen folder-Objekt die Methode getMessageCount() nutzen.



Beispiel Um eine Nachricht vom Server zu löschen, darf der Ordner nicht mit READ_ONLY geöffnet werden, sondern mit Folder.READ_WRITE. Anschließend lässt sich einer Nachricht, repräsentiert durch ein Message-Objetkt, mit setFlag() ein Lösch-Hinweis geben.

message.setFlag( Flags.Flag.DELETED, true );

Die Daten werden jedoch nur dann vom Server gelöscht, wenn zum Schluss folder.close(true) aufgefufen wird. Ohne den Aufruf von close() mit dem Parameter true bleiben die Nachrichten erhalten.







1 Der E-Mail-Client von Microsoft zieht Probleme mit sich, denen die meisten von uns lieber aus dem Weg gehen würden. Als in der Fernsehwerbung zwischen 1996 und 1997 der Internet Explorer beworben wurde, spielte im Hintergrund die Musik vom Wolfgang Amadeus Mozart (1756-1791). In Mozarts Requiem, welches geschichtlich gesehen schon mit Verwunderungen verbunden war, taucht am Ende der Werbung der Choral »Confutatis maledictis, flammis acribus addictis« auf. Zeitgleich folgt der Microsoft-Slogan »Where do you want to go today?«. Für die Nicht-Lateiner wird es erst bei der Übersetzung lustig: »Die Verdammten und Angeklagten, die in den Flammen der Hölle verurteilt sind«.





Copyright (c) Galileo Press GmbH 2004
Für Ihren privaten Gebrauch dürfen Sie die Online-Version natürlich ausdrucken. Ansonsten unterliegt das <openbook> denselben Bestimmungen, wie die gebundene Ausgabe: Das Werk einschließlich aller seiner Teile ist urheberrechtlich geschützt. Alle Rechte vorbehalten einschließlich der Vervielfältigung, Übersetzung, Mikroverfilmung sowie Einspeicherung und Verarbeitung in elektronischen Systemen.


[Galileo Computing]

Galileo Press GmbH, Gartenstraße 24, 53229 Bonn, Tel.: 0228.42150.0, Fax 0228.42150.77, info@galileo-press.de