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.4 Das Common Gateway Interfacedowntop

CGI (Common Gateway Interface) ist eine Beschreibung einer Schnittstelle http://cgi-spec. golux.com/, mit der externe Programme mit Informations-Servern, meistens Web-Servern, Daten austauschen. Die aktuelle Version ist CGI/1.1. Diese ausgeführten Programme werden kurz CGI-Programme genannt und können in allen erdenklichen Programmiersprachen verfasst sein. Häufig sind es Shell-/Python- oder Perl-Skripte (oft wird dann die Bezeichnung CGI-Skripte verwendet). Die Unterscheidung zwischen Skript und Programm ist bei CGI schwammig. Traditionell ist eine compilierte Quelldatei ein Programm, und Programme, die mit einem Interpreter arbeiten, sind ein Skript. Wir werden im Folgenden allerdings »Programm« und »Skript« synonym verwenden. Für uns ist es erst einmal egal, ob ein Programm oder ein Skript ausgeführt wird, denn wir wollen diese Programme aus Java nutzen und nicht selber schreiben. Auf der Server-Seite ergänzen und verdrängen Java Server Pages beziehungsweise Servlets immer stärker CGI-Programme.

Die CGI-Programme werden von einem Browser durch eine ganz normale URL angesprochen. Der Browser baut eine Verbindung zum Server auf, und dieser erkennt anhand des Pfads oder anderer Kriterien (Dateiendung oder spezielle Dateiflags), ob es sich um eine ganz normale Web-Seite handelt oder um ein Skript. Wenn es ein Skript ist, dann führt der Server das Skript aus, welches eine HTML-Datei erzeugt. Diese wird übertragen und im Browser dargestellt. Der Aufrufer einer URL merkt keinen Unterschied (außer vielleicht in der Performance) zwischen erstellten, also dynamischen, und statischen Seiten. Die CGI-Programme sind also immer eine Angelegenheit des Servers, der uns mit aktuellen Daten versorgt.


Galileo Computing

16.4.1 Parameter für ein CGI-Programmdowntop

Beim Aufruf eines CGI-Programms können Parameter übergeben werden, bei einer Suchmaschine etwa der Suchbegriff. Es gibt nun zwei Möglichkeiten, wie diese Parameter zum Skript kommen und somit vom Web-Server verarbeitet werden.

gp Die Parameter (auch Query-Strings genannt) werden an die URL angehängt (GET-Methode). Das Skript liest die Daten aus der CGI-Umgebungsvariablen QUERY_STRING aus.
gp Die Daten werden zur Standardeingabe des Web-Servers gesendet (POST-Methode). Das Skript muss dann aus dieser Eingabe lesen.

GET und POST unterscheiden sich auch in der Länge der übertragenen Daten. Bei vielen Systemen ist die Länge einer GET-Anfrage beschränkt auf 1024 Byte. POST-Anfragen sind längenunbegrenzt.

Daten werden nach der GET-Methode verschickt

Die Daten sind mit dem CGI-Programmnamen verbunden und gehen beide zusammen auf die Reise. Der Anfrage-String (Query-String) wird hinter ein Fragezeichen gesetzt, das Et-Zeichen »&« trennt mehrere Anfragezeichenketten. Unter Java setzen wir einfach einen Befehl ab, indem wir ein neues URL-Objekt erzeugen und anschließend den Inhalt auslesen:

meineURL = new URL( "http", "...", "cgi-bin/trallala?tri" );

Das CGI-Skript holt sich seinerseits die Daten aus der Umgebungsvariablen QUERY_STRING. Das folgende Kapitel zeigt, wie diese Abfragezeichenketten komfortabel durch die Klasse URLEncoder zusammengebaut werden. Werfen wir jedoch erst einen Blick auf die Variablen.

Daten holen mit der POST-Methode

Die Klasse URLConnection bietet die schon bekannte Methode getOutputStream() an, die eine Verbindung zur Eingabe des CGI-Scripts möglich macht (POST-Methode):

// CGI-Script schickt die Daten zurück
PrintStream o = new PrintStream( cgiConnection.getOutputStream() );
o.println( data );
o.close();

Galileo Computing

16.4.2 Kodieren der Parameter für CGI-Programmedowntop

Wenn aus einer HTML-Datei mit Formularen über Submit Daten an das CGI-Programm übermittelt werden, dann werden diese Daten kodiert. Dies liegt daran, dass viele Zeichen in URL nicht erlaubt sind. Betrachten wir daher folgenden Ausschnitt aus einer Web-Seite:

<form method="get" action="/cgi-bin/caller.cgi">
<p>Name:
<input type="text" name="name" value="">
<p>E-Mail:
<input type="text" name="email" value="">
<p>
<input type="submit" name="submit" >
</form>

Die Seite besitzt zwei Felder mit den Namen name und email. Dazu kommt noch ein Submit-Button, der, falls aktiviert, die Daten an das CGI-Programm caller.cgi weitergibt. Wenn wir die Felder mit irgendeinem Inhalt füllen und Submit drücken, sehen wir die URL häufig in der Adressleiste des Browsers. Dort erscheint, ohne Zeilenumbruch, zum Beispiel:

http://oho.de/cgi-bin/caller.cgi?
name=Ulli+Ullenboom&email=ulliull@ulli.com&submit=Submit

Da in einer URL keine Leerzeichen erlaubt sind, werden sie durch Pluszeichen kodiert. Es gibt noch weitere Zeichen, die kodiert werden, so das Plus- oder das Gleichheitszeichen oder auch das Und-Symbol. Von diesen Zeichen wird die Hex-Repräsentation als ASCII übersandt, aus »Ulli + Tanja« wird dann »Ulli+%2B+Tanja«. Aus dem Leerzeichen wird ein Plus und aus dem Plus wird %2B.

Neben der Textkodierung fällt noch auf, dass in der übermittelten Zeile jeder Feldname und das Feld mit seinem Feldinhalt übermittelt wird. Somit lässt sich leicht der Inhalt eines Felds heraussuchen, denn nach dem Feldnamen ist ein Gleichheitszeichen eingefügt. Das Ende der Inhalte ist durch ein Und-Zeichen gekennzeichnet.

Wollten wir einen String dieser Art zu einer URL zusammenbauen, um etwa eine Anfrage an ein Suchprogramm zu formulieren, dann müssen wir den String nicht kodieren. Dies übernimmt die Java-Klasse URLEncoder.

Abbildung
Hier klicken, um das Bild zu Vergrößern

Listing 16.6 URLEncodeTest.java

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
public class URLEncoderDemo
{
  static void enc( String s )
  {
    try
    {
      System.out.println( URLEncoder.encode( s, "UTF-8" ) );
    }
    catch ( UnsupportedEncodingException e )
    {
      e.printStackTrace();
    }
  }
  
  public static void main( String args[] )
  {
    enc( "String mit Leerezeichen" ); // String+mit+Leerezeichen
    enc( "String%mit%Prozenten" );    // String%25mit%25Prozenten
    enc( "String*mit*Sternen" );      // String*mit*Sternen
    enc( "String+hat+ein+Plus" );     // String%2Bhat%2Bein%2BPlus
    enc( "String/mit/Slashes" );      // String%2Fmit%2FSlashes
    enc( "String\"mit\"Gänsen" );     // String%22mit%22G%C3%A4nsen
    enc( "String:Doppelpunkten" );    // String%3ADoppelpunkten
    enc( "String=ist=alles=gleich" ); // String%3Dist%3Dalles%3Dgleich
    enc( "String&String&String" );    // String%26String%26String
    enc( "String.mit.Punkten");       // String.mit.Punkten
  }
}

class java.net.URLEncoder

gp static String encode( String s, String enc ) throws UnsupportedEncodingException
Kodiert einen String s mit einer bestimmten Encoding.

class java.net.URLDecoder

gp static String decode( String s, String enc ) throws UnsupportedEncodingException
Dekodiert einen String s mit einer bestimmten Encoding.

Galileo Computing

16.4.3 Eine Suchmaschine ansprechentoptop

Wir wollen nun direkt eine Suchmaschine ansprechen und so das Verhalten eines Anfrageprogramms nachbilden. Unser Programm sammelt dazu alle Suchbegriffe als Parameter auf der Kommandozeile, falls keine Parameter vorhanden sind, wird nach »Teletubbies on Tour« gesucht. Anschließend kodiert die Klasse URLEncoder den Such-String, und der Inhalt wird hinter die URL des CGI-Programms gehängt, noch getrennt durch ein Fragezeichen. Dieses wird als Anfrage für die Suchmaschine Google verpackt und weggeschickt. Anschließend wird in einer Schleife die HTML-Datei zeilenweise ausgegeben.

Listing 16.7 GoogleSeeker.java

import java.io.*;
import java.net.*;
public class GoogleSeeker
{
  public static void main( String args[] ) throws Exception
  {
    String s = "";
    if ( args.length == 0 )
      s = "Teletubbies On Tour";
    else
      for ( int i = 0; i < args.length; i++ )
        s += args[i] + " ";
    s.trim();
    s = "q=" + URLEncoder.encode( s, "UTF-8" );
    URL u = new URL( ">http://www.google.com/search?"; + s );
    BufferedReader in = new BufferedReader(
      new InputStreamReader( u.openStream() ) );
    String line, response = null;
    while ( (line = in.readLine()) != null )
      response += line+"\n";
    System.out.print( response );
  }
}




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