BA Horb Seminarbericht Software-Engineering _________________________________________________________ Netzwerkprogrammierung mit Java _________________________________________________________ Autoren Daniel Adametz [email protected] Anton Suchanov [email protected] Betreuer Olaf Herden Bearbeitungszeitraum KW39-45 2005 Abstract: In diesem Bericht sind die wichtigsten Informationen zum Thema Netzwerkprogrammierung mit Java zusammengefasst. Es werden die wichtigsten Klassen zum Einstieg in die Kommunikation mittels Java vorgestellt. Daniel Adametz Anton Succhanov Seite 2 Inhaltsverzeichnis Inhaltsverzeichnis ............................................................................................................. 3 Abkürzungen..................................................................................................................... 5 1. Grundlagen Verbindungen/Internet .......................................................................... 6 1.1. Einleitung.............................................................................................................. 6 1.2. Das Hypertext Transfer Protocol (HTTP)............................................................. 6 1.3. Host- und IP-Adressen .......................................................................................... 7 1.3.1. Host................................................................................................................ 7 1.3.2. IP-Nummer .................................................................................................... 7 1.3.3. Ports ............................................................................................................... 8 1.3.4. Host-Name ..................................................................................................... 8 1.3.5. Paket .............................................................................................................. 8 1.3.6. Router/Switch ................................................................................................ 9 1.4. Internet-Standards und RFC.................................................................................. 9 1.5. Socket.................................................................................................................... 9 2. Client/Server-Kommunikation.................................................................................. 9 2.1. Das Netzwerk ist der Computer .......................................................................... 10 2.2. StreamSocket ...................................................................................................... 10 2.3. Stream ................................................................................................................. 10 2.4. SSL-Verbindungen mit JSSE.............................................................................. 11 2.5. Apache Jakarta Commons HttpClient und Net ................................................... 11 3. URL-Verbindungen und URL-Objekte................................................................... 12 3.1. Die Klasse URL .................................................................................................. 12 Konstruktor dieser Klasse ........................................................................................... 13 3.2. Informationen über eine URL ............................................................................. 13 3.3. Der Zugriff auf die Daten über die Klasse URL ................................................. 13 3.4. Die Klasse URLConnection................................................................................ 14 3.5. Protokoll- und Content-Handler.......................................................................... 14 3.6. Bilder-Handler .................................................................................................... 15 3.7. Content- und Protocol-Handler ........................................................................... 15 3.8. Autorisierte URL-Verbindungen mit Basic Authentication ......................................... 16 Daniel Adametz Anton Succhanov Seite 3 4. E-Mail ..................................................................................................................... 16 4.1. Wie eine E-Mail um die Welt geht ..................................................................... 16 4.2. SMTP, POP und RFC 822 .................................................................................. 18 4.3. E-Mails versenden mit der JavaMail API ........................................................... 19 4.4. MimeMultipart-Nachrichten schicken ................................................................ 19 4.5. E-Mails mittels POP3 abrufen ............................................................................ 20 4.6. Ereignisse und Suchen ........................................................................................ 20 5. Datagram-Sockets (UDP) ....................................................................................... 21 5.1.1. Datagramme und die Klasse DatagramPacket ............................................. 22 5.1.2. Auf ein hereinkommendes Paket warten...................................................... 24 5.1.3. Ein Paket zum Senden vorbereiten .............................................................. 24 5.1.4. Das Paket senden ......................................................................................... 24 5.1.5. Zeitdienste mittels UPD............................................................................... 25 5.2. Tiefer liegende Netzwerkeigenschaften .............................................................. 25 5.2.1. MAC-Adresse .............................................................................................. 25 5.2.2. Internet Control Message Protocol (ICMP) ................................................. 25 5.2.3. Multicast-Kommunikation........................................................................... 26 6. Literaturverzeichniss............................................................................................... 26 Daniel Adametz Anton Succhanov Seite 4 Abkürzungen • ARPA……………………….Advanced Research Projects Agency • DARPA……………………..Defense Advanced Research Projects Agency • DNS…………………………Domain Name Service • FTP………………………….File Transport Protocol • FQHN ………………………Fully Qualified Host Name • http…………………………..Hypertext Transfer Protocol • POP………………………….Post Office Protocoll • RFC………………………....Request For Comments • SMTP……………………......Simple Mail Tranport Protocol • TCP/IP………………………Transmission Control Protocol/Internet Protocol • UDP…………………………User Datagram Protocol • URL………………………....Uniform Resource Locator Daniel Adametz Anton Succhanov Seite 5 1. Grundlagen Verbindungen/Internet 1.1. Einleitung Ein Netzwerk ist die Verbindung von zwei oder mehreren Rechnern zum Zwecke des Datenaustausches, so kann man Computernetzwerke in ihren Anfängen beschreiben. Heutzutage sind weitaus komplexere Anwendungen mit Netzwerken möglich, jedoch steht immer noch der Datenaustausch im Vordergrund. Hierzu ein paar Beispiele: • Dateien auf zentralen Servern speichern (Sicherheitskopien) • Nutzung gemeinsamer Drucker oder Faxgeräte • Verbindung verschiedener (Groß-) Rechner zur Leistungssteigerung (Cluster) • Verbreitung von Informationen im lokalen Intranet • Synchronisieren der Uhrzeit beim Booten • u.v.m. 1.2. Das Hypertext Transfer Protocol (HTTP) Das HTTP ist ein Protokoll für Multimedia-Systeme und im RFC 2616 genau beschrieben. HTTP wird seit dem Aufkommen des World Wide Web intensiv genutzt. Das Web basiert auf der Seitenbeschreibungssprache HTML, die 1992 von Tim BernersLee entwickelt wurde. Die Entwicklung wurde am CERN vorgenommen, und seit den Prototypen ist die Entwicklung nicht nur im Bereich HTML fortgeschritten, sondern auch im Protokoll. Html ist ein Werkzeug zur Veröffentlichung wissenschaftlicher Berichte ermöglichen wollte. HTTP definiert eine Kommunikation zwischen Client und Server. Typischerweise horcht der Server auf Port 80 (oder 8080) auf Anfragen des Clients. Das Protokoll benutzt eine TCP/IP-Socket-Verbindung und ist textbasiert. Alle HTTP-Anfragen haben ein allgemeines Format: Daniel Adametz Anton Succhanov Seite 6 1. Eine Zeile am Anfang Dies kann entweder eine Anfrage (also eine Nachricht vom Client) oder eine Antwort vom Server sein. 2. Ein paar Kopf-Zeilen (engl. header) Informationen über den Client oder Server, zum Beispiel über den Inhalt. Der Header endet immer mit einer Leerzeile. 3. Einen Körper (engl. body) Der Inhalt der Nachricht. Entweder Benutzerdaten vom Client oder die Antwort vom Server Dieses Protokoll ist also sehr einfach und auch unabhängig von Datentypen. Dies macht es ideal einsetzbar für verteilte Informationssysteme. 1.3. Host- und IP-Adressen 1.3.1. Host Eine Maschine (Rechner) im Netzwerk, die durch eine eindeutige Adresse (IP-Nummer bzw. MAC-Adresse) angesprochen werden kann. 1.3.2. IP-Nummer Eine eindeutige Adresse, die jeden Host im Internet kennzeichnet. Die Adresse ist für IPv4 eine 32 Bit-Zahl, die in die Teile Host und Netzwerk (Subnet) untergliedert ist. z.Bsp.: 192.168.0.1/16 Das neuere IPv6 sieht eine 128-Bit-Zahl vor. z.Bsp.: 1080:0:0:0:8:800:200C:417A /64 oder die Kurzform (ohne Null) 1080::8:800:200C:417A /64 Daniel Adametz Anton Succhanov Seite 7 1.3.3. Ports Da auf einer Maschine unterschiedliche Server laufen können, wurde zu den IPAdressen noch ein weiteres Merkmal hinzugefügt, die Port-Nummer. Diese wird von der Anwendung, also dem Server gesteuert. Eine Portnummer ist eine 16bit Zahl und teilt sich in System- (0-1023) und Benutzergruppe (1024-65535). Jeder Servertyp hat seinen eigenen Port, viele davon sind Standards geworden. Die nachfolgende Tabelle zeigt einige wichtige Ports. Dienst Port Beschreibung ftp-data 20 File Transfer [Default Data] ftp 21 File Transfer [Control] smtp 25 Simple Mail Transfer www-http 80 World Wide Web/HTTP pop3 110 Post Office Protocol - Version 3 1.3.4. Host-Name Ein symbolischer Name für die IP-Nummer der Maschine. Durch Techniken wie DNS und Suns NIS werden diese auf die IP-Adressen abgebildet. Diese Abbildungstabellen werden z.Bsp. in Deutschland verwaltet von der DENIC eG. 1.3.5. Paket Kurzform für ein Datenpaket, was eine Dateneinheit in der Informationsübertragung darstellt, die über das Netzwerk verschickt wird. Oft auch als Frame bezeichnet. Der größte Teil von Datenpaketen besteht aus den zu verschickenden Informationen. Außerdem enthält es wichtige Adressierungs- und Verwaltungsinformationen - in IPbasierten Netzwerken zum Beispiel die Quell- und Ziel-IP-Adressen, um das Paket an den richtigen Rechner zu liefern. Pakete nehmen meist nicht den selben Weg im physikalischen Netz, sondern werden geroutet. Daniel Adametz Anton Succhanov Seite 8 1.3.6. Router/Switch Ein Host, der Pakete teilweise auspackt und zwischen verschiedenen Netzwerken weiterreicht. Router bzw. Switches machen die Unterteilung in verschiedene virtuelle LAN´s durch nur ihnen bekannten Routingtabellen möglich, was zur Erhöhung der Performanz sowie der Netzwerksicherheit beiträgt. 1.4. Internet-Standards und RFC Die meisten der allgemeinen Protokolle sind in den Request For Comments, kurz RFC beschrieben. Dies sind Entwürfe, Empfehlungen und Standarts zum Internet. Derzeit sind etwa 2500 RFC´s beschrieben. Viele Server stellen die RFC´s zur Verfügung, u.a. z.Bsp. http://rfc.fh-koeln.de. 1.5. Socket Sockets sind Verbindungspunkte in einem TCP/IP Netzwerk und dienen zur Abstraktion. Jeder Rechner in einem Netzwerk implementiert einen Socket. Wenn ein Rechner Daten empfangen soll, öffnet er eine Socket-Verbindung zum hörchen (listening) und derjenige, der senden will öffnet eine Socket-Verbindung zum senden. Damit Sender und Empfänger sich gegenseitig „sehen“ können, bekommt jeder von ihnen eine eindeutige numerische Adresse (IP-Adresse). 2. Client/Server-Kommunikation Die Netzwerk-Klassen in Java bieten ein unterschiedliches Einstiegsniveau. Einerseits besteht die Möglichkeit, mittels Sockets auf einer relativ niedrigen Ebene zu arbeiten. Andererseits stehen auch Klassen wie URL zur Verfügung, die bereits einen Großteil der Daniel Adametz Anton Succhanov Seite 9 Netzwerkfunktionalität beinhalten. Im Folgenden werden exemplarisch einige Möglichkeiten der beiden Klassen Socket und URL vorgestellt. 2.1. Das Netzwerk ist der Computer Wie am Anfang bereits beschrieben, besteht das kleinste Netzwerk aus zwei untereinander verbunden Rechner. Die Rechner kommunizieren im Netz über Protokolle. Das TCP/IP Protokoll hat sich am stärksten durchgesetzt und wird heute überwiegend verwendet. Dieses Protokoll wurde von der Universität von Berkeley im Auftrag von der ARPA (jetzt DARPA), der US-amerikanischen Forschungsbehörde entwickelt. 2.2. StreamSocket Eine vom Stream-Socket aufgebaute Verbindung ist fest und bleibt für die Dauer der Übertragung bestehen, was bei anderen Formen von Sockets nicht der Fall ist. Mit den Netzwerkklassen unter Java lassen sich sowohl Client- als auch Server-basierte Programme schreiben. Beispiel einer Verbindung zu einem Server: Socket clientSocket = new Socket( "die.weite.welt", 80 ); Dieser Aufruf erzeugt einen Socket und verbindet ihn zum Host die.weite.welt am Port 80. Kann die Verbindung nicht hergestellt werden so wird eine UnknownHostException ausgelöst. 2.3. Stream Wenn die Verbindung steht, wird die Datenübertragung so wie bei Dateien auf der Festplatte behandelt. Die Klasse Socket liefert uns Streams, die das Lesen und Schreiben ermöglichen. Folgende Funktionen stehen dafür zur Verfügung getInputStream() und getOutputStream(). Daniel Adametz Anton Succhanov Seite 10 Beispiel-Code: .... OutputStream out = server.getOutputStream() .... InputStream Liefert den Eingabestrom für den Socket. OutputStream liefert den Ausgabestrom für den Socket. Beide Ströme lösen eine Exception aus, falls ein Fehler passiert. 2.4. SSL-Verbindungen mit JSSE Verschlüsselte, sichere Kommunikationen spielen eine immer größere Rolle im täglichen Datenverkehr. Hierzu bietet die JSSE (Java Secure Socket Extension), eine JavaErweiterung die Möglichkeit zu sicheren Verbindungen im Internet. JSSE implementiert das verbreitete Protokoll SSL (Secure Sockets Layer) und TLS (Transport Layer Security) und erlaubt damit Verschlüsselung, Server-Authentifizierung und Integrität von Nachrichten. TLS ist ein Nachfolger von SLL und basiert weitestgehend darauf. Mit TLS lassen sich jedoch Verschlüsselungsverfahren flexibler auswechseln, da TLS ein echtes Transportprotokoll ist. Da SSL/TLS direkt unter dem Applikationsprotokoll sitzt, lassen sich damit Dienste wie HTTP, Telnet, NNTP oder FTS sichern. JSSE ist seit 1.4 enthalten. JSSE definiert das Paket javax.net und javax.net.ssl mit den wichtigen Klassen SSLSocket und SSLSocketFactory, welche im Jar-Archiv jsse.jar gebündelt sind. 2.5. Apache Jakarta Commons HttpClient und Net Das Java-Netzwerkpaket und insbesondere die Klasse URLConnection beziehungsweise HttpConnection bieten Basisfunktionalität für den Zugriff auf Internet-Ressourcen. Allerdings fehlen komfortable Methoden, etwa für Cookies oder Multi-Part Form-Data POST, also Möglichkeiten zum Hochladen von Dateien. Die müsste jeder selbst implementieren, was Zeit und Nerven kostet. Die Bibliothek Jakarta Commons HttpClient bietet komfortable Unterstützung für alles mögliche rund um das HTTP-Protokoll 1.0 und 1.1: Daniel Adametz Anton Succhanov Seite 11 Alle HTTP Methoden (GET, POST, PUT, DELETE, HEAD, OPTIONS, TRACE) Verschlüsselung mit HTTPS (HTTP über SSL) Verbindungen durch HTTP-Proxies Getunnelte HTTPS Verbindungen durch HTTP-Proxies, via CONNECT Verbindungen mit SOCKS-Proxies (Version 4 und 5) Authentifizierung mit BASIC, Digest und NTLM (NT Lan Manager) Multi-Part Form POST und vieles mehr 3. URL-Verbindungen und URL-Objekte 3.1. Die Klasse URL URL ist die Abkürzung für 'Uniform Resource Locator'. Es handelt sich um die Adresse eines Dokumentes im Internet, bestehend aus Typ (Dienst), Ort (Rechner, Verzeichnis) und Dateinamen. Mit der URL werden die Ressourcen im Web adressiert. Es ist ein „Dateisystem“ fürs Internet. In Java kann eine URL-Verbindung sehr einfach hergestellt werden. Dafür wird ein Objekt der Klasse URL erstellt. Daniel Adametz Anton Succhanov Seite 12 Konstruktor dieser Klasse In der nachfolgenden Tabelle sind die wichtigsten Konstruktoren dieser Klasse aufgeführt. Beispiel Erklärung URL url = new Webadresse liegt als String vor URL("http://www.google.de") URL jtURL = new URL( "http", "java- Komponenten der Adresse sind einzeln tutor.com", "index.html" ) gegeben, wobei der zweite Parameter relativ zu sehen ist URL url = new URL( "http", "java- ein entfernter Rechner kann auch an tutor.com", 80, "index.html" ) einem anderen Port angesprochen werden Jeder der Konstruktoren wirft eine Exception vom Typ MalformedURLException, wenn der Konstruktor falsch parametriert ist oder ein unbekanntes Protokoll verwendet wird. Aufgrund dessen wird ein URL – Objekt innerhalb eines „Try-Catch“ Blocks erzeugt. 3.2. Informationen über eine URL Sobald das URL-Objekt einmal angelegt ist, lassen sich Attribute des Objekts erfragen, aber leider nicht mehr ändern. Uns normalen Klassenbenutzern bietet die URL-Klasse nur Methoden zum Zugriff. So lassen sich Protokoll, Host-Name, Port-Nummer und Dateiname mit Zugriffsmethoden erfragen. Es lassen sich jedoch nicht alle URLAdressen so detailliert aufschlüsseln, und außerdem sind manche der Zugriffsmethoden nur für HTTP sinnvoll. 3.3. Der Zugriff auf die Daten über die Klasse URL Um auf die auf dem Web-Server gespeicherten Daten zuzugreifen, gibt es drei Möglichkeiten. Zwei davon nutzen Streams, und zwar einmal über die Klasse URL und Daniel Adametz Anton Succhanov Seite 13 einmal über eine URLConnection. Die dritte Möglichkeit erfordert etwas Handarbeit, sie wird ausführlich im Kapitel über Sockets beschrieben. Jedes URL-Objekt besitzt die Methode openStream(), die einen InputStream zum Weiterverarbeiten liefert, so dass wir dort die Daten auslesen können: InputStream in = myUrl.openStream(); Verweist die URL auf eine Textdatei, dann erweitern wir oft den InputStream zu einem BufferedReader, da dieser eine readLine()-Methode besitzt. Glücklicherweise ist uns die Art des Vorgehens schon bekannt, da sich ja das Lesen von einer Datei nicht vom Lesen eines entfernten URL-Objekts unterscheidet. 3.4. Die Klasse URLConnection Die Klasse URL Connection ist für den Empfang des Inhalts der Klasse URL. Diese Klasse ist sehr stark auf HTTP ausgerichtet, denn viele Methoden haben nur für Webseiten Sinn und Bedeutung. 3.5. Protokoll- und Content-Handler Wenn ein passender Content-Handler installiert ist, bietet getContent() Zugriff auf den Inhalt eines URL-Objektes. Diese Methode funktioniert bei allen Objekten, vorausgesetzt das richtige Protokoll ist installiert. Content-Handler erweitert die Funktionalität der URL Klasse. Es können Quellen verschiedener MIME-Typen durch die Methode getContent() als Objekte zurückgegeben werden. Die Java-Spezifikation beschreibt nicht, welche Content-Handler bereitgestellt werden müssen. Auch ein Protokoll-Handler erweitert die Klasse URL. Das Protokoll ist der erste Teil einer URL und gibt bei Übertragungen das Kommunikationsverfahren an. Auch ein Protokoll-Handler erweitert die Möglichkeiten der URL-Klassen. Das Protokoll gibt bei Übertragungen die Kommunikationsmethode an. Daniel Adametz Anton Succhanov Seite 14 3.6. Bilder-Handler Für Bilder ist ein Handler eingetragen, der als Rückgabewert ein URLImageSource liefert. Wenn wir konkret ein Bild über eine URL laden wollen, dann bietet sich sicherlich die einfachere Methode getImage(URL) an. Die Vorgehensweise, mit getContent() an Daten zu gelangen, funktioniert für alle Objekte – natürlich muss ein passendes Protokoll installiert sein. Für Content-Handler gilt das Gleiche wie für Protokoll-Handler: Unterschiedliche Umgebungen implementieren unterschiedliche Handler. Leider gibt es keine Methode in der Bibliothek, die sofort die Daten in einem String bereitstellt. 3.7. Content- und Protocol-Handler Wenn ein passender Content-Handler installiert ist, bietet getContent() Zugriff auf den Inhalt eines URL-Objektes. Diese Methode funktioniert bei allen Objekten, vorausgesetzt das richtige Protokoll ist installiert. Content-Handler erweitert die Funktionalität der URL Klasse. Es können Quellen verschiedener MIME-Typen durch die Methode getContent() als Objekte zurückgegeben werden. Die Java-Spezifikation beschreibt nicht, welche Content-Handler bereitgestellt werden müssen. Auch ein Protokoll-Handler erweitert die Klasse URL. Das Protokoll ist der erste Teil einer URL und gibt bei Übertragungen das Kommunikationsverfahren an. Auch ein Protokoll-Handler erweitert die Möglichkeiten der URL-Klassen. Das Protokoll gibt bei Übertragungen die Kommunikationsmethode an. Daniel Adametz Anton Succhanov Seite 15 3.8. Autorisierte URL-Verbindungen mit Basic Authentication URL-Verbindungen können durch die Basic Authentication (Nutzer & Passwort) geschützt sein. Der Server schickt eine Anforderung an den Client sich zu autorisieren. Das Java-Programm muss den Benutzernamen und das dazugehörige Passwort zurückschicken. 4. E-Mail 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. 4.1. Wie eine E-Mail um die Welt geht In einem E-Mail-System kommen mehrere Komponenten vor, die in Tabelle kurz benannt sind. User Der Benutzer des Mail-Systems, der Nachrichten verschickt oder empfängt Mail User Agent (MUA) Die Schnittstelle zwischen dem Benutzer und dem Mail-System Message Store (MS) Dient dem Mail User Agent zum Ablegen der Nachrichten. Message Transfer Agent (MTA) Dies sind Komponenten des Message Transfer Systems und verantwortlich für die eigentliche Nachrichtenübermittlung. Message Transfer System (MTS) Ist die Gesamtheit der Message Transfer Agents und ihrer Verbindungen. Tabelle 1 Komponenten E-Mail-System Daniel Adametz Anton Succhanov Seite 16 Abbildung 1 Ablauf einer E-Mail Kommunikation 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. Daniel Adametz Anton Succhanov Seite 17 4.2. SMTP, POP und RFC 822 Für die Übertragung von E-Mail hat sich auf breite Basis das Simple Mail Transfer Protocol (kurz SMTP) etabliert. SMTP ist ein Versende-Protokoll, welches im RFC 2821 beschrieben ist. Zusammen mit dem RFC 822, welches den Austausch von textbasierten Nachrichten im Internet beschreibt, bildet dies das Gerüst des MailSystems. Das aus dem Jahr 1982 stammende SMTP wird heute immer mehr zum Hindernis, da die kommerzielle 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 FQNH 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. 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. Daniel Adametz Anton Succhanov Seite 18 4.3. E-Mails versenden mit der JavaMail API Die JavaMail API, eine eigene Bibliothek, die zum Versenden und Empfangen von EMail, lässt sich von http://java.sun.com/products/javamail/ beziehen. Zudem muss das Archiv activation.jar für das JavaBeans Activation Framework mit im Klassenpfad aufgenommen werden. Bei Enterprise-Applikationen sind die Archive Bestandteil einer J2EE-Installation. Um eine E-Mail mit JavaMail zu verwenden, sind nicht viele Klassen zu verstehen: Session steht für eine Verbindung mit dem Mail-Server, Message (bzw. MimeMessage) für die zu versendende Nachricht und Addresse repräsentiert einen Sender und die Empfänger. Die Klasse Transport ist für den Versand zuständig. 4.4. MimeMultipart-Nachrichten schicken 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-Teilen zu kodieren. Die JavaMail-API bietet für diesen Fall die Klasse (Mime)Multipart an; eine Containerklasse, der mit addBodyPart() diverse (Mime)BodyPart-Objekte hinzugefügt werden können. Zum Schluss – sind die Köper aufgebaut – setzt auf dem MessageObjekt setContent() nun nicht mehr das einfache MimeMessage-Objekt mit einem expliziten MIME-Typ, sondern das MMO. 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. Daniel Adametz Anton Succhanov Seite 19 4.5. E-Mails mittels POP3 abrufen Die andere Seite soll ebenso betrachtet werden. Sie ist ein klein wenig aufwändiger. Die auf dem Server liegenden Nachrichten (Message-Objekte) müssen erst dekodiert werden. Die Nachrichten werden aber nicht vom Server gelöscht. 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. Die Daten werden jedoch nur dann vom Server gelöscht, wenn zum Schluss folder.close(true) aufgerufen wird. Ohne den Aufruf von close() mit dem Argument true bleiben die Nachrichten erhalten. 4.6. Ereignisse und Suchen Die Tabelle 2 zeigt einige Glanzstücke der JavaMail-API, unter ihnen ein System für verschiedene Ereignisse. Listener Angewendet auf Aufgaben MessageCountListener Folder Findet, wenn neue Nachrichten kommen. (Bei POP3 muss Postfach geschlossen sein.) ConnectionListener Service (Store, Transport), Folder Benachrichtigung beim Öffnen, Schließen, Zwangstrennung FolderListener Folder Ordner angelegt, umbenannt, gelöscht MessageChangedListener Folder Änderung, etwa am Folder oder Headern StoreListener Store Nachricht mit Wichtigkeit ALERT oder NOTICE TransportListener Transport Zugestellt, nicht zugestellt, zum Teil zugestellt Tabelle 2 Event Listener in JavaMail-API Daniel Adametz Anton Succhanov Seite 20 Das zweite ist ein Suchsystem, den JavaMail über das Paket javax.mail.search definiert. Zunächst wird ein Suchterm aus SearchTerm-Objekten aufgebaut. Diese abstrate Basisklasse definiert eine Methode match(), die von Unterklassen passende implemekntiert wird: AddressTerm und Unterklassen FromTerm, RecipientTerm durchsuchen Absender und Empfänger StringTerm. Sucht nach Teilzeichenketten. FlagTerm. Testet, ob Nachrichten gewisse Flags besitzen DateTerm sucht mit Unterklassen ReceivedDateTerm und SentDateTerm nach Datum AndTerm, NotTerm, OrTerm. Verknüpfungen zwischen Termen Tabelle 3 5. Datagram-Sockets (UDP) Neben den Stream-Sockets gibt es im java.net-Paket eine weitere Klasse, die auch den verbindungslosen Pakettransport erlaubt. Es handelt sich dabei um die Klasse DatagramSocket, die auf UDP basieren. Dies ist auf IP aufgesetzt und erlaubt eine ungesicherte Übertragung. Auch UDP erlaubt es einer Applikation, einen Service über einen Port zu kontaktieren. Genau wie TCP nutzt auch UDP verschiedene PortNummern, so dass mehrere Server unter unterschiedlichen Ports ihre Dienste anbieten können. Wichtig ist, dass UDP-Ports völlig eigenständig sind und mit TCP-Ports nichts gemeinsam haben. So kann ein TCP- Socket als auch ein Datagram-Socket am selben Port horchen. Die Datagram-Sockets benötigen im Gegensatz zu den Stream-Sockets keine feste Verbindung zum Server; jedes Datagramm wird einzeln verschickt und kann folglich auf verschiedenen Wegen und in verschiedener Reihenfolge am Client ankommen. So ist der Ausdruck »verbindungslos« zu verstehen. Die Datagramme sind Daniel Adametz Anton Succhanov Seite 21 von den anderen völlig unabhängig. Ist die Ordnung der Pakete relevant, muss über ein Zeitfeld dann die richtige Reihenfolge rekonstruiert werden. 5.1.1. Datagramme und die Klasse DatagramPacket Stream-Sockets nutzen eine TCP/IP-Verbindung und die Fähigkeit, Daten in der richtigen Reihenfolge zu sortieren. Arbeiten wir also mit Stream-Sockets oder auch mit der URL-Klasse, so müssen wir uns um den Transport nicht kümmern. Wir werden also bei der Benutzung von Stream-Sockets von den unteren Netzwerkschichten getrennt, die die richtige Reihenfolge der Pakete garantieren. Datagram-Sockets nutzen ein anderes Protokoll: das UDP-Protokoll. Dabei wird nur ein einzelner Chunk – durch die Klasse DatagramPacket repräsentiert – übertragen, dessen Größe wir fast frei bestimmen können. Fast, weil die Größe vom IP-Protokoll vorgegeben ist und maximal 64 KB (65.535 Byte) zur Verfügung stehen. Mehr Daten können wir mit einer Übertragung nicht senden. Es ist somit unsere Aufgabe, größere Pakete zu zerteilen. TCP würde diese Pakete dann wieder richtig zusammensetzen, doch UDP leistet dies nicht. Deswegen garantiert UDP auch nicht, dass die Reihenfolge der Pakete richtig ist. Da UDP nicht mit verlorenen Paketen umgehen kann, ist es nicht gewährleistet, dass alle Daten übertragen werden. Die Anwendung muss sich also selbst darum kümmern. Das hört sich jetzt alles mehr nach einem Nachteil als nach einem Vorteil an. Warum werden dann überhaupt Datagram-Sockets verwendet? Die Antwort ist einfach: DatagramSockets sind schnell. Da die Verbindung nicht verbindungsorientiert ist wie TCP/IP, lässt sich der Aufwand für die korrekte Reihenfolge und noch weitere Leistungen sparen. Verbindungslose Protokolle wie eben UDP bauen keine Verbindung zum Empfänger auf und senden dann die Daten, sondern sie senden einfach die Daten und lassen sie von den Zwischenstationen verteilen. UDP profitiert also davon, dass die Bestätigung der Antwort und die erlaubte Möglichkeit des Sendens nicht vereinbart werden. UDP sendet seine Pakete demnach einfach in den Raum, und es ist egal, ob sie ankommen oder nicht. Daniel Adametz Anton Succhanov Seite 22 Da allerdings Pakete verloren gehen können, würden wir Datagram-Sockets nicht für große Daten verwenden. Für kleine, öfters übermittelte Daten eignet sich das Protokoll besser. Hier geht also Geschwindigkeit vor Sicherheit. Das bedeutet, UDP kann überall dort eingesetzt werden, wo eine Empfangsbestätigung nicht relevant ist. Erhält ein Client innerhalb einer gewissen Zeit keine Antwort, so stellt er seine Anfrage einfach erneut. Wichtige Applikationen, die UDP nutzen, sind das DNS, TFTP und auch Suns Network Filesystem (NFS). NFS ist so ausgelegt, dass verloren gegangene Pakete wieder besorgt werden. Welche Klasse für welche Übertragung verwenden? Im Gegensatz zu TCP-Verbindungen gibt es bei UDP-Verbindungen kein Objekt wie Socket oder ServerSocket für Client und Server. Das liegt daran, dass es in UDP kein Konzept wie virtuelle Verbindungen gibt und die Adresse nicht im Socket gespeichert ist, sondern im Paket selbst. Bei UPD verwenden beide die Klasse DatagramSocket, welche für eine eingehende und auch ausgehende Verbindung steht. Klasse Protokoll Verbindungstyp Socket TCP ServerSocket TCP DatagramSocket UDP Richtung Verbindungsorientiert, korrekte Reihenfolge Verbindungsorientiert, korrekte Reihenfolge Anton Succhanov Hereinkommend Verbindungslos, Datagramme, Ausgehend und beliebige Reihenfolge hereinkommend Tabelle 4 Welche Klasse wofür? Daniel Adametz Ausgehend Seite 23 5.1.2. Auf ein hereinkommendes Paket warten Wenn wir Daten empfangen, dann müssen wir nur ein DatagramPacket-Objekt anlegen und den Speicherplatz angeben, an dem die Daten abgelegt werden sollen. Das Feld ist so etwas wie ein Platzhalter. Wenn wir empfangen wollen, müssen wir warten, bis ein Paket eintrifft. Das geschieht mit der DatagramSocket-Methode receive(DatagramPacket). Die Methode ist vergleichbar mit der accept()-Methode der Klasse ServerSocket, nur dass accept() ein Socket-Objekt zurückgibt und receive() die Daten in dem als Argument übergebenen DatagramPacket ablegt. Mit den Methoden getPort() und getAddress() können wir herausfinden, woher das Paket kam, wer also der Sender war. Mit getData() bekommen wir die Daten als Bytefeld, und getLength() liefert die Länge. Ist das empfangene Paket größer als unser Puffer, wird das Feld nur bis zur maximalen Größe gefüllt. 5.1.3. Ein Paket zum Senden vorbereiten Wenn wir ein Paket senden wollen, dann müssen wir einem DatagramPacket auch noch sagen, wohin die Reise geht, das heißt, der Port und die IP-Adresse des entfernten Rechners sind anzugeben. Der Empfänger wird durch ein InetAddress-Objekt repräsentiert, der Konstruktor ist leider nicht mit einem String-Objekt überladen, was sicherlich nützlich wäre. Es gibt aber einen speziellen Konstruktor, der die Inet-Adresse und den Port direkt entgegennimmt. 5.1.4. Das Paket senden Zum Senden eines DatagramPacket dient die DatagramSocket-Methode send(DatagramPacket). Sie schickt das Datagram an die im DatagramPacket enthaltene Port-Nummer und -Adresse. Im oberen Beispiel hatten wir diese Informationen einmal ausgelesen. Die Reihenfolge für Sendevorgänge ist also immer die gleiche: Ein Datagram-Socket mit einem Standard-Konstruktor erzeugen, das DatagramPaket-Objekt Daniel Adametz Anton Succhanov Seite 24 mit dem Port und der Inet-Adresse des Empfängers erzeugen, dann schickt send() das Paket auf die Reise. 5.1.5. Zeitdienste mittels UPD Beliebt Anwendung von UDP ist ein Zeit-Server. Dieser bietet Clients immer die aktuelle Server-Uhrzeit an. Ein Server lauscht auf Port 13 nach UDP-Paketen und sendet dann die Antwort, die mittels Daytime Protocol beschrieben ist an den Sender, dessen Adresse er aus dem Paket nimmt. 5.2. 5.2.1. Tiefer liegende Netzwerkeigenschaften MAC-Adresse Die MAC-Adresse ist eine (im Idealfall) eindeutige Adresse einer Netzwerkkarte. MACAdressen sind für Ethernet-Verbindungen essentiell, da auf der physikalischen Übertragungsebene Signale zu einer gewünschten Netzwerkkarte aufgebaut werden. Wegen der Eindeutigkeit eigenen sie sich gut als Schlüssel und es wäre interessant, auch in Java diese Adresse auszulesen. Das geht jedoch nur über einen Umweg über JNI oder über einen Konsolenaufruf, welchen die MAC-Adresse liefert. 5.2.2. Internet Control Message Protocol (ICMP) ICMP, ein Steuerprotokol welches ebenfalls auf der Vermittlungsschicht eingesetzt wird um unerwartete Ereignisse und Zusatzinformationen zur Diagnose von Routern bzw. Switches zu melden. ICPM ist ein einfaches IP-Paket mit bestimmten Flags, welches im RFC 792 definiert ist. In Java können mit den Standardbibliotheken keine IP-Pakete und ICMP-Nachrichten verschickt werden, um Rechts- und Sicherheitsproblemen vorzubeugen. Daniel Adametz Anton Succhanov Seite 25 5.2.3. Multicast-Kommunikation Besteht die Notwendigkeit, dass ein Server Datagramme gleichzeitig an mehrere Clients schickt, dann müssen wir hier auch mehrere einzelne Verbindungen (so genannte Unicast-Verbindungen) aufbauen. Diese Möglichkeit ist jedoch sehr ineffizient und belastet die Bandbreite. Anwendungsfelder für Multicast-Kommunikation sind etwa Video oder Audio, Chat-Sitzungen oder interaktive Spiele. In Java lässt sich für diese Aufgabe das Multicasting einsetzen, wenn das Betriebssystem und die Router Multicasting-fähig sind. Damit der Server sendet und mehrere Clients empfangen können, melden sich die Clients bei einer gewünschten Multicast-Gruppe an. Eine Multicast-Gruppe besteht aus mehreren Rechnern, die sich eine Multicast-Adresse teilen. Der Server sendet dann die Datagramme über einen Multicast-Socket und wird von allen in der Liste empfangen. Die weitere Verarbeitung übernehmen das Betriebssystem und die Router. Für eine Multicast-Gruppe gibt es spezielle MulticastAdressen. Diese bewegen sich im Bereich von 224.0.0.0 bis 239.255.255.255. Statische Multicast-Adressen werden – wie andere IP-Adressen auch – von der IANA vergeben. Für eigene Testzwecke bieten sich Adressen im Bereich 224.0.1.27 und 224.0.1.225 an. 6. Literaturverzeichniss Bücher: • Java ist auch eine Insel von Christian Ullenboom; ISBN: 3898427471 • Thread- und Netzwerk- Programmierung mit Java. Ein Praktikum für die Parallele Programmierung von Heinz Kredel und Akitoshi Yoshida; ISBN: 3932588282 • Handbuch der Java-Programmierung von Guido Krüger ISBN: 3827319498 Internet: • http://www.codeguru.com • http://www.wikipedia.de Daniel Adametz Anton Succhanov Seite 26