From 33613a85afc4b1481367fbe92a17ee59c240250b Mon Sep 17 00:00:00 2001 From: Sven Eisenhauer Date: Fri, 10 Nov 2023 15:11:48 +0100 Subject: add new repo --- .../hjp5/html/k100295.html | 803 +++++++++++++++++++++ 1 file changed, 803 insertions(+) create mode 100644 Master/Reference Architectures and Patterns/hjp5/html/k100295.html (limited to 'Master/Reference Architectures and Patterns/hjp5/html/k100295.html') diff --git a/Master/Reference Architectures and Patterns/hjp5/html/k100295.html b/Master/Reference Architectures and Patterns/hjp5/html/k100295.html new file mode 100644 index 0000000..24c07cb --- /dev/null +++ b/Master/Reference Architectures and Patterns/hjp5/html/k100295.html @@ -0,0 +1,803 @@ + + + +Handbuch der Java-Programmierung, 5. Auflage + + + + + + + + + +
 Titel  + Inhalt  + Suchen  + Index  + DOC  +Handbuch der Java-Programmierung, 5. Auflage +
 <<  +  <   +  >   + >>  + API  +Kapitel 46 - Netzwerkprogrammierung +
+
+ + + + +

46.3 Server-Sockets

+
+ +
+ + + + +

46.3.1 Die Klasse ServerSocket

+ +

+In den bisherigen Abschnitten hatten wir uns mit dem Entwurf von Netzwerk-Clients +beschäftigt. Nun wollen wir uns das passende Gegenstück +ansehen, uns also mit der Entwicklung von Servern beschäftigen. +Glücklicherweise ist auch das in Java recht einfach. Der wesentliche +Unterschied liegt in der Art des Verbindungsaufbaus, für den +es eine spezielle Klasse ServerSocket +gibt. Diese Klasse stellt Methoden zur Verfügung, um auf einen +eingehenden Verbindungswunsch zu warten und nach erfolgtem Verbindungsaufbau +einen Socket +zur Kommunikation mit dem Client zurückzugeben. Bei der Klasse +ServerSocket +sind im wesentlichen der Konstruktor und die Methode accept +von Interesse: +

+ + + + + +
+ +
+public ServerSocket(int port)
+  throws IOException
+
+public Socket accept()
+  throws IOException
+
+
+
+java.net.ServerSocket
+ +

+Der Konstruktor erzeugt einen ServerSocket +für einen bestimmten Port, also einen bestimmten Typ von Serveranwendung +(siehe Abschnitt 46.1.4). +Anschließend wird die Methode accept +aufgerufen, um auf einen eingehenden Verbindungswunsch zu warten. +accept +blockiert so lange, bis sich ein Client bei der Serveranwendung anmeldet +(also einen Verbindungsaufbau zu unserem Host unter der Portnummer, +die im Konstruktor angegeben wurde, initiiert). Ist der Verbindungsaufbau +erfolgreich, liefert accept +ein Socket-Objekt, +das wie bei einer Client-Anwendung zur Kommunikation mit der Gegenseite +verwendet werden kann. Anschließend steht der ServerSocket +für einen weiteren Verbindungsaufbau zur Verfügung oder +kann mit close +geschlossen werden. + +

+Wir wollen uns die Konstruktion von Servern an einem Beispiel ansehen. +Dazu soll ein einfacher ECHO-Server geschrieben werden, der auf Port +7 auf Verbindungswünsche wartet. Alle eingehenden Daten sollen +unverändert an den Client zurückgeschickt werden. Zur Kontrolle +sollen sie ebenfalls auf die Konsole ausgegeben werden: + + +

+ + + + + +
+ +
+001 /* SimpleEchoServer.java */
+002 
+003 import java.net.*;
+004 import java.io.*;
+005 
+006 public class SimpleEchoServer
+007 {
+008   public static void main(String[] args)
+009   {
+010     try {
+011       System.out.println("Warte auf Verbindung auf Port 7...");
+012       ServerSocket echod = new ServerSocket(7);
+013       Socket socket = echod.accept();
+014       System.out.println("Verbindung hergestellt");
+015       InputStream in = socket.getInputStream();
+016       OutputStream out = socket.getOutputStream();
+017       int c;
+018       while ((c = in.read()) != -1) {
+019         out.write((char)c);
+020         System.out.print((char)c);
+021       }
+022       System.out.println("Verbindung beenden");
+023       socket.close();
+024       echod.close();
+025     } catch (IOException e) {
+026       System.err.println(e.toString());
+027       System.exit(1);
+028     }
+029   }
+030 }
+
+
+SimpleEchoServer.java
+ +Listing 46.5: Ein ECHO-Server für Port 7

+ +

+Wird der Server gestartet, kann via Telnet oder mit dem EchoClient +aus Listing 46.3 auf +den Server zugegriffen werden: + +

+telnet localhost 7
+
+ + +

+Wenn der Server läuft, werden alle eingegebenen Zeichen direkt +vom Server zurückgesendet und als Echo in Telnet angezeigt. Läuft +er nicht, gibt es beim Verbindungsaufbau eine Fehlermeldung. +

+ + + + + + + + + +
+ +

+Wird das Programm unter UNIX gestartet, kann es möglicherweise +Probleme geben. Einerseits kann es sein, dass bereits ein ECHO-Server +auf Port 7 läuft. Er könnte nötigenfalls per Eintrag +in inetd.conf +oder ähnlichen Konfigurationsdateien vorübergehend deaktiviert +werden. Andererseits dürfen Server auf Ports kleiner 1024 nur +mit Root-Berechtigung gestartet werden. Ein normaler Anwender darf +dagegen nur Server-Ports größer 1023 verwenden.

+ + + + +
 Hinweis 
+
+ + + + +

46.3.2 Verbindungen zu mehreren Clients

+ +

+Wir wollen das im vorigen Abschnitt vorgestellte Programm nun in mehrfacher +Hinsicht erweitern: +

+ +

+Um diese Anforderungen zu erfüllen, verändern wir das obige +Programm ein wenig. Im Hauptprogramm wird nun nur noch der ServerSocket +erzeugt und in einer Schleife jeweils mit accept +auf einen Verbindungswunsch gewartet. Nach dem Verbindungsaufbau erfolgt +die weitere Bearbeitung nicht mehr im Hauptprogramm, sondern es wird +ein neuer Thread mit dem Verbindungs-Socket als Argument erzeugt. +Dann wird der Thread gestartet und erledigt die gesamte Kommunikation +mit dem Client. Beendet der Client die Verbindung, wird auch der zugehörige +Thread beendet. Das Hauptprogramm braucht sich nur noch um den Verbindungsaufbau +zu kümmern und ist von der eigentlichen Client-Kommunikation +vollständig befreit. + + +

+ + + + + +
+ +
+001 /* EchoServer.java */
+002 
+003 import java.net.*;
+004 import java.io.*;
+005 
+006 public class EchoServer
+007 {
+008   public static void main(String[] args)
+009   {
+010     int cnt = 0;
+011     try {
+012       System.out.println("Warte auf Verbindungen auf Port 7...");
+013       ServerSocket echod = new ServerSocket(7);
+014       while (true) {
+015         Socket socket = echod.accept();
+016         (new EchoClientThread(++cnt, socket)).start();
+017       }
+018     } catch (IOException e) {
+019       System.err.println(e.toString());
+020       System.exit(1);
+021     }
+022   }
+023 }
+024 
+025 class EchoClientThread
+026 extends Thread
+027 {
+028   private int    name;
+029   private Socket socket;
+030 
+031   public EchoClientThread(int name, Socket socket)
+032   {
+033     this.name   = name;
+034     this.socket = socket;
+035   }
+036 
+037   public void run()
+038   {
+039     String msg = "EchoServer: Verbindung " + name;
+040     System.out.println(msg + " hergestellt");
+041     try {
+042       InputStream in = socket.getInputStream();
+043       OutputStream out = socket.getOutputStream();
+044       out.write((msg + "\r\n").getBytes());
+045       int c;
+046       while ((c = in.read()) != -1) {
+047         out.write((char)c);
+048         System.out.print((char)c);
+049       }
+050       System.out.println("Verbindung " + name + " wird beendet");
+051       socket.close();
+052     } catch (IOException e) {
+053       System.err.println(e.toString());
+054     }
+055   }
+056 }
+
+
+EchoServer.java
+ +Listing 46.6: Eine verbesserte Version des Echo-Servers

+ +

+Zur besseren Übersicht werden alle Client-Verbindungen durchnummeriert +und als erstes Argument an den Thread übergeben. Unmittelbar +nach dem Verbindungsaufbau wird diese Meldung auf der Server-Konsole +ausgegeben und an den Client geschickt. Anschließend wird in +einer Schleife jedes vom Client empfangene Zeichen an diesen zurückgeschickt, +bis er von sich aus die Verbindung unterbricht. Man kann den Server +leicht testen, indem man mehrere Telnet-Sessions zu ihm aufbaut. Jeder +einzelne Client sollte eine Begrüßungsmeldung mit einer +eindeutigen Nummer erhalten und autonom mit dem Server kommunizieren +können. Der Server sendet alle Daten zusätzlich an die Konsole +und gibt sowohl beim Starten als auch beim Beenden eine entsprechende +Meldung auf der Konsole aus. + + + + +

46.3.3 Entwicklung eines einfachen Web-Servers

+ +

+In Abschnitt 46.2.4 war +schon angeklungen, dass ein Web-Server in seinen Grundfunktionen so +einfach aufgebaut ist, dass wir uns hier eine experimentelle Implementierung +ansehen können. Diese ist nicht nur zu Übungszwecken nützlich, +sondern wird uns in Kapitel 47 +bei der RMI-Programmierung behilflich sein, Bytecode »on demand« +zwischen Client und Server zu übertragen. + +

+Die Kommunikation zwischen einem Browser und einem Web-Server entspricht +etwa folgendem Schema: +

+ +

+Hat der Browser auf diese Weise eine HTML-Seite erhalten, interpretiert +er den HTML-Code und zeigt die Seite formatiert auf dem Bildschirm +an. Enthält die Datei IMG-, APPLET- oder ähnliche Elemente, +werden diese in derselben Weise vom Server angefordert und in die +Seite eingebaut. Die wichtigste Aufgabe des Servers besteht also darin, +eine Datei an den Client zu übertragen. Wir wollen uns zunächst +das Listing ansehen und dann auf Details der Implementierung eingehen: + + +

+ + + + + +
+ +
+001 /* ExperimentalWebServer.java */
+002 
+003 import java.io.*;
+004 import java.util.*;
+005 import java.net.*;
+006 
+007 /**
+008  * Ein ganz einfacher Web-Server auf TCP und einem
+009  * beliebigen Port. Der Server ist in der Lage,
+010  * Seitenanforderungen lokal zu dem Verzeichnis,
+011  * aus dem er gestartet wurde, zu bearbeiten. Wurde
+012  * der Server z.B. im Verzeichnis c:\tmp gestartet, so
+013  * würde eine Seitenanforderung
+014  * http://localhost:80/test/index.html die Datei
+015  * c:\tmp\test\index.html laden. CGIs, SSIs, Servlets
+016  * oder ähnliches wird nicht unterstützt.
+017  * <p>
+018  * Die Dateitypen .htm, .html, .gif, .jpg und .jpeg werden
+019  * erkannt und mit korrekten MIME-Headern übertragen, alle
+020  * anderen Dateien werden als "application/octet-stream"
+021  * übertragen. Jeder Request wird durch einen eigenen
+022  * Client-Thread bearbeitet, nach Übertragung der Antwort
+023  * schließt der Server den Socket. Antworten werden mit
+024  * HTTP/1.0-Header gesendet.
+025  */
+026 public class ExperimentalWebServer
+027 {
+028   public static void main(String[] args)
+029   {
+030     if (args.length != 1) {
+031       System.err.println(
+032         "Usage: java ExperimentalWebServer <port>"
+033       );
+034       System.exit(1);
+035     }
+036     try {
+037       int port = Integer.parseInt(args[0]);
+038       System.out.println("Listening to port " + port);
+039       int calls = 0;
+040       ServerSocket httpd = new ServerSocket(port);
+041       while (true) {
+042         Socket socket = httpd.accept();
+043         (new BrowserClientThread(++calls, socket)).start();
+044       }
+045     } catch (IOException e) {
+046       System.err.println(e.toString());
+047       System.exit(1);
+048     }
+049   }
+050 }
+051 
+052 /**
+053  * Die Thread-Klasse für die Client-Verbindung.
+054  */
+055 class BrowserClientThread
+056 extends Thread
+057 {
+058   static final String[][] mimetypes = {
+059     {"html", "text/html"},
+060     {"htm",  "text/html"},
+061     {"txt",  "text/plain"},
+062     {"gif",  "image/gif"},
+063     {"jpg",  "image/jpeg"},
+064     {"jpeg", "image/jpeg"},
+065     {"jnlp", "application/x-java-jnlp-file"}
+066   };
+067 
+068   private Socket       socket;
+069   private int          id;
+070   private PrintStream  out;
+071   private InputStream  in;
+072   private String       cmd;
+073   private String       url;
+074   private String       httpversion;
+075 
+076   /**
+077    * Erzeugt einen neuen Client-Thread mit der angegebenen
+078    * id und dem angegebenen Socket.
+079    */
+080   public BrowserClientThread(int id, Socket socket)
+081   {
+082     this.id     = id;
+083     this.socket = socket;
+084   }
+085 
+086   /**
+087    * Hauptschleife für den Thread.
+088    */
+089   public void run()
+090   {
+091     try {
+092       System.out.println(id + ": Incoming call...");
+093       out = new PrintStream(socket.getOutputStream());
+094       in = socket.getInputStream();
+095       readRequest();
+096       createResponse();
+097       socket.close();
+098       System.out.println(id + ": Closed.");
+099     } catch (IOException e) {
+100       System.out.println(id + ": " + e.toString());
+101       System.out.println(id + ": Aborted.");
+102     }
+103   }
+104 
+105   /**
+106    * Liest den nächsten HTTP-Request vom Browser ein.
+107    */
+108   private void readRequest()
+109   throws IOException
+110   {
+111     //Request-Zeilen lesen
+112     Vector request = new Vector(10);
+113     StringBuffer sb = new StringBuffer(100);
+114     int c;
+115     while ((c = in.read()) != -1) {
+116       if (c == '\r') {
+117         //ignore
+118       } else if (c == '\n') { //line terminator
+119         if (sb.length() <= 0) {
+120           break;
+121         } else {
+122           request.addElement(sb);
+123           sb = new StringBuffer(100);
+124         }
+125       } else {
+126         sb.append((char)c);
+127       }
+128     }
+129     //Request-Zeilen auf der Konsole ausgeben
+130     Enumeration e = request.elements();
+131     while (e.hasMoreElements()) {
+132       sb = (StringBuffer)e.nextElement();
+133       System.out.println("< " + sb.toString());
+134     }
+135     //Kommando, URL und HTTP-Version extrahieren
+136     String s = ((StringBuffer)request.elementAt(0)).toString();
+137     cmd = "";
+138     url = "";
+139     httpversion = "";
+140     int pos = s.indexOf(' ');
+141     if (pos != -1) {
+142       cmd = s.substring(0, pos).toUpperCase();
+143       s = s.substring(pos + 1);
+144       //URL
+145       pos = s.indexOf(' ');
+146       if (pos != -1) {
+147         url = s.substring(0, pos);
+148         s = s.substring(pos + 1);
+149         //HTTP-Version
+150         pos = s.indexOf('\r');
+151         if (pos != -1) {
+152           httpversion = s.substring(0, pos);
+153         } else {
+154           httpversion = s;
+155         }
+156       } else {
+157         url = s;
+158       }
+159     }
+160   }
+161 
+162   /**
+163    * Request bearbeiten und Antwort erzeugen.
+164    */
+165   private void createResponse()
+166   {
+167     if (cmd.equals("GET") || cmd.equals("HEAD")) {
+168       if (!url.startsWith("/")) {
+169         httpError(400, "Bad Request");
+170       } else {
+171         //MIME-Typ aus Dateierweiterung bestimmen
+172         String mimestring = "application/octet-stream";
+173         for (int i = 0; i < mimetypes.length; ++i) {
+174           if (url.endsWith(mimetypes[i][0])) {
+175             mimestring = mimetypes[i][1];
+176             break;
+177           }
+178         }
+179         //URL in lokalen Dateinamen konvertieren
+180         String fsep = System.getProperty("file.separator", "/");
+181         StringBuffer sb = new StringBuffer(url.length());
+182         for (int i = 1; i < url.length(); ++i) {
+183           char c = url.charAt(i);
+184           if (c == '/') {
+185             sb.append(fsep);
+186           } else {
+187             sb.append(c);
+188           }
+189         }
+190         try {
+191           FileInputStream is = new FileInputStream(sb.toString());
+192           //HTTP-Header senden
+193           out.print("HTTP/1.0 200 OK\r\n");
+194           System.out.println("> HTTP/1.0 200 OK");
+195           out.print("Server: ExperimentalWebServer 0.5\r\n");
+196           System.out.println(
+197             "> Server: ExperimentalWebServer 0.5"
+198           );
+199           out.print("Content-type: " + mimestring + "\r\n\r\n");
+200           System.out.println("> Content-type: " + mimestring);
+201           if (cmd.equals("GET")) {
+202             //Dateiinhalt senden
+203             byte[] buf = new byte[256];
+204             int len;
+205             while ((len = is.read(buf)) != -1) {
+206               out.write(buf, 0, len);
+207             }
+208           }
+209           is.close();
+210         } catch (FileNotFoundException e) {
+211           httpError(404, "Error Reading File");
+212         } catch (IOException e) {
+213           httpError(404, "Not Found");
+214         } catch (Exception e) {
+215           httpError(404, "Unknown exception");
+216         }
+217       }
+218     } else {
+219       httpError(501, "Not implemented");
+220     }
+221   }
+222 
+223   /**
+224    * Eine Fehlerseite an den Browser senden.
+225    */
+226   private void httpError(int code, String description)
+227   {
+228     System.out.println("> ***" + code + ": " + description + "***");
+229     out.print("HTTP/1.0 " + code + " " + description + "\r\n");
+230     out.print("Content-type: text/html\r\n\r\n");
+231     out.println("<html>");
+232     out.println("<head>");
+233     out.println("<title>ExperimentalWebServer-Error</title>");
+234     out.println("</head>");
+235     out.println("<body>");
+236     out.println("<h1>HTTP/1.0 " + code + "</h1>");
+237     out.println("<h3>" + description + "</h3>");
+238     out.println("</body>");
+239     out.println("</html>");
+240   }
+241 }
+
+
+ExperimentalWebServer.java
+ +Listing 46.7: Ein experimenteller Web-Server

+ +

+Der Web-Server besteht aus den beiden Klassen ExperimentalWebServer +und BrowserClientThread, die +nach dem in Abschnitt 46.3.2 +vorgestellten Muster aufgebaut sind. Nachdem in ExperimentalWebServer +eine Verbindung aufgebaut wurde, wird ein neuer Thread erzeugt und +die weitere Bearbeitung des Requests an ein Objekt der Klasse BrowserClientThread +delegiert. Der in run +liegende Code beschafft zunächst die Ein- und Ausgabestreams +zur Kommunikation mit dem Socket und ruft dann die beiden Methoden +readRequest und createResponse +auf. Anschließend wird der Socket geschlossen und der Thread +beendet. + +

+In readRequest wird der HTTP-Request +des Browsers gelesen, der aus mehreren Zeilen besteht. In der ersten +wird die eigentliche Dateianforderung angegeben, die übrigen +liefern Zusatzinformationen wie den Typ des Browsers, akzeptierte +Dateiformate und ähnliches. Alle Zeilen werden mit CRLF abgeschlossen, +nach der letzten Zeile des Requests wird eine Leerzeile gesendet. +Entsprechend der Empfehlung in RFC1945 ignoriert unser Parser die +'\r'-Zeichen und erkennt das Zeilenende anhand eines '\n'. So arbeitet +er auch dann noch korrekt, wenn ein Client die Headerzeilen versehentlich +mit einem einfachen LF abschließt. + +

+Ein typischer Request könnte etwa so aussehen (in diesem Beispiel +wurde er von Netscape 4.04 unter Windows 95 generiert): + +

+GET /ansisys.html HTTP/1.0
+Connection: Keep-Alive
+User-Agent: Mozilla/4.04 [en] (Win95; I)
+Host: localhost:80
+Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, image/png, */*
+Accept-Language: en
+Accept-Charset: iso-8859-1,*,utf-8
+HTTP/1.0 200 OK
+Server: ExperimentalWebServer 0.5
+Content-type: text/html
+
+ + +

+Unser Web-Server liest den Request zeilenweise in den Vector +request ein und gibt alle Zeilen +zur Kontrolle auf der Konsole aus. Anschließend wird das erste +Element extrahiert und in die Bestandteile Kommando, URL +(Dateiname) und HTTP-Version zerlegt. Diese Informationen werden +zur weiteren Verarbeitung in den Membervariablen cmd, +url und httpversion +gespeichert. + +

+Nachdem der Request gelesen wurde, wird in createResponse +die Antwort erzeugt. Zunächst prüft die Methode, ob es sich +um ein GET- +oder HEAD-Kommando +handelt (HTTP kennt noch mehr). Ist das nicht der Fall, wird durch +Aufruf von httpError eine Fehlerseite +an den Browser gesendet. Andernfalls fährt die Methode mit der +Bestimmung des Dateityps fort. Der Dateityp wird mit Hilfe der Arraykonstante +mimetypes anhand der Dateierweiterung +bestimmt und in einen passenden MIME-Typ +konvertiert, der im Antwortheader an den Browser übertragen wird. +Der Browser entscheidet anhand dieser Information, was mit der nachfolgend +übertragenen Datei zu tun ist (Anzeige als Text, Anzeige als +Grafik, Speichern in einer Datei usw.). Wird eine Datei angefordert, +deren Erweiterung nicht bekannt ist, sendet der Server sie als application/octet-stream +an den Browser, damit dieser dem Anwender die Möglichkeit geben +kann, die Datei auf der Festplatte zu speichern. +

+ + + + + + + + + +
+ +

+Der Mime-Typ application/x-java-jnlp-file +wird für den Betrieb von Java Web Start +benötigt. Dieses seit dem JDK 1.4 verfügbare Werkzeug zum +Laden, Aktualisieren und Starten von Java-Programmen über Internet-Verbindungen +wird ausführlich in Abschnitt 13.5 +erläutert.

+ + + + +
 Hinweis 
+
+ +

+Nun wandelt der Server den angegebenen Dateinamen gemäß +den Konventionen seines eigenen Betriebssystems um. Dazu wird das +erste »/« aus dem Dateinamen entfernt (alle Dateien werden +lokal zu dem Verzeichnis geladen, aus dem der Server gestartet wurde) +und alle »/« innerhalb des Pfadnamens werden in den lokalen +Pfadseparator konvertiert (unter MS-DOS ist das beispielsweise der +Backslash). Dann wird die Datei mit einem FileInputStream +geöffnet und der HTTP-Header und der Dateiinhalt an den Client +gesendet. Konnte die Datei nicht geöffnet werden, wird eine Ausnahme +ausgelöst und der Server sendet eine Fehlerseite. + +

+Der vom Server gesendete Header ist ähnlich aufgebaut wie der +Request-Header des Clients. Er enthält mehrere Zeilen, die durch +CRLF-Sequenzen voneinander getrennt sind. Nach der letzten Headerzeile +folgt eine Leerzeile, also zwei aufeinanderfolgende CRLF-Sequenzen. +HTTP 1.0 und 1.1 spezifizieren eine ganze Reihe von (optionalen) Headerelementen, +von denen wir lediglich die Versionskennung, unseren Servernamen und +den MIME-Bezeichner mit der Typkennung der gesendeten Datei an den +Browser übertragen. Unmittelbar nach dem Ende des Headers wird +der Dateiinhalt übertragen. Eine Umkodierung erfolgt dabei normalerweise +nicht, alle Bytes werden unverändert übertragen. + +

+Unser Server kann sehr leicht getestet werden. Am einfachsten legt +man ein neues Unterverzeichnis an und kopiert die übersetzten +Klassendateien und einige HTML-Dateien in dieses Verzeichnis. Nun +kann der Server wie jedes andere Java-Programm gestartet werden. Beim +Aufruf ist zusätzlich die Portnummer als Argument anzugeben: + +

+java ExperimentalWebServer 80
+
+ + +

+Nun kann ein normaler Web-Browser verwendet werden, um Dateien vom +Server zu laden. Befindet sich beispielsweise eine Datei index.html +im Server-Verzeichnis und läuft der Server auf derselben Maschine +wie der Browser, kann die Datei über die Adresse http://localhost/index.html +im Browser geladen werden. Auch über das lokale Netz des Unternehmens +oder das Internet können leicht Dateien geladen werden. Hat der +Host, auf dem der Server läuft, keinen Nameserver-Eintrag, kann +statt dessen auch direkt seine IP-Adresse im Browser angegeben werden. +

+ + + + + + + + + + + +
+ +

+Auf einem UNIX-System darf ein Server die Portnummer 80 nur verwenden, +wenn er Root-Berechtigung hat. Ist das nicht der Fall, kann der Server +alternativ auf einem Port größer 1023 gestartet werden: + +

+java ExperimentalWebServer 7777
+
+ + +

+Im Browser muss die Adresse dann ebenfalls um die Portnummer ergänzt +werden: http://localhost:7777/index.html. +

+ + + + +
 Warnung 
+
+


+ + + +
 Titel  + Inhalt  + Suchen  + Index  + DOC  +Handbuch der Java-Programmierung, 5. Auflage, Addison +Wesley, Version 5.0.1 +
 <<  +  <   +  >   + >>  + API  +© 1998, 2007 Guido Krüger & Thomas +Stark, http://www.javabuch.de +
+ + + -- cgit v1.2.3