13.5Host- und IP-Adressen
Der Datenaustausch im Internet geschieht durch kleine IP-Pakete. Sie bilden die Basis der Internetübertragung. Immer wenn ein Netzwerkpaket übermittelt werden soll, werden IP-Pakete erzeugt und dann auf die Reise geschickt. Der Empfänger der Pakete ist ein Rechner, der im Netz durch eine Kennung, die numerische IP-Adresse, identifiziert wird. Diese Zahl ist für die meisten Menschen schwer zu behalten, weshalb oft der Hostname Verwendung findet, um einen Rechner im Internet anzusprechen. Die Konvertierung von Hostnamen in IP-Adressen übernimmt ein Domain Name Server (DNS). Baut eine Anwendung – etwa ein Internet-Browser – eine Verbindung zu einem Rechner auf, so hilft eine Betriebssystemfunktion, die IP-Adresse für den Rechnernamen zu ermitteln. An diese Adresse kann dann im nächsten Schritt eine Webanfrage gestellt werden.
Abbildung 13.3Vererbungsbeziehung von InetAddress und Unterklassen
Auch wir können in Java zu einem Namen die IP-Adresse erfragen und auch umgekehrt vorgehen und zu einer IP-Adresse den Rechnernamen erfragen – sofern verfügbar. Die Anweisungen laufen über die Klasse InetAddress, die eine Internetadresse repräsentiert. Das Objekt wird durch Fabrikmethoden wie getByName(String) oder getAllByName(String) erzeugt. Gebotene getXXX()-Methoden erfragen dann Resultate, die die Auflösung ergeben hat:
Listing 13.10com/tutego/insel/net/MyDNS.java
System.out.println( inet.getCanonicalHostName() ); // web1.networkaholics.de
System.out.println( inet.getHostAddress() ); // 82.96.100.30
System.out.println( inet.getHostName() ); // www.tutego.com
System.out.println( inet.toString() ); // www.tutego.com/82.96.100.30
inet = InetAddress.getByName( "193.99.144.71" );
System.out.println( inet.getHostName() ); // web.heise.de
Erfreulicherweise ist es möglich, an Stelle des Rechnernamens auch die IP-Adresse anzugeben; getHostName() nimmt dann eine umgekehrte Auflösung vor. So liefert InetAddress.getByName("193.99.144.71").getHostName() den String »www.heise.de«.
implements Serializable
static InetAddress getByName(String host) throws UnknownHostException
Liefert die IP-Adresse eines Hosts anhand des Namens. Der Hostname kann als Maschinenname (»tutego.com«) angegeben sein oder als numerische Repräsentation der IP-Adresse (»66.70.168.193«).static InetAddress[] getAllByName(String host) throws UnknownHostException
Wie getByName(String), doch liefert es mehrere Objekte für den Fall, dass es zusätzliche Adressen gab.String getHostName()
Liefert den Hostnamen.String getHostAddress()
Liefert die IP-Adresse als String im Format »%d.%d.%d.%d«.String getCanonicalHostName()
Liefert den voll qualifizierten Domänennamen (FQDN), sofern das möglich ist.byte[] getAddress()
Gibt ein Feld mit Oktetten – der Internetbezeichnung für Bytes – für die IP-Adresse zurück.
13.5.1Lebt der Rechner?
Verwaltet das InetAddress-Objekt einen Rechnernamen, so kann das Objekt durch Versenden von Testpaketen überprüfen, ob der Rechner im Internet »lebt«. Dazu dient isReachable(int); das Argument ist eine Anzahl von Millisekunden, die wir dem Prüfvorgang geben wollen.
Listing 13.11com/tutego/insel/net/IsReachable.java, main()
InetAddress.getByName( "100.100.100.100" ).isReachable( 2000 ) // false
[+]Tipp
Um Probleme mit der Namensauflösung auszuschließen, sollte die IP-Adresse verwendet werden, da der Namensdienst einen Fehler melden wird, falls er den symbolischen Namen nicht auflösen kann. Und dieser Fehler hat nichts mit der Erreichbarkeit zu tun.
13.5.2IP-Adresse des lokalen Hosts
Auch dazu benutzen wir die Klasse InetAddress. Sie besitzt die statische Methode getLocalHost().
Listing 13.12com/tutego/insel/net/GetLocalIP.java, main()
Das Programm erzeugt zum Beispiel eine Ausgabe der folgenden Art:
Apropos lokaler Rechner: Die Methode isSiteLocalAddress() liefert true, wenn das InetAddress-Objekt für den eigenen Rechner steht, also eine IP-Adresse wie 192.168.0.0 hat.
implements Serializable
static InetAddress getLocalHost() throws UnknownHostException
Liefert ein IP-Adressen-Objekt des lokalen Hosts.boolean isSiteLocalAddress()
Repräsentiert diese InetAddress eine lokale Adresse?
Die statische Methode getAllByName(String host)
Die Klasse InetAddress bietet die statische Methode getLocalHost(String) an, um die eigene Adresse herauszufinden. Bei mehreren vergebenen IP-Adressen des Rechners lässt sich dann mit einigen wenigen Zeilen alles ausgeben. Dazu lässt sich die statische Methode InetAddress.getAllByName(String) nutzen, die alle mit einem Rechner verbundenen InetAddress-Objekte liefert.
Listing 13.13com/tutego/insel/net/GetAllByName.java, main()
for ( InetAddress ia : InetAddress.getAllByName(localHost) )
System.out.println( ia );
[»]Hinweis
Läuft ein Java-Programm und wird die IP-Adresse eines Rechners geändert, dann wird Java diese Änderung nicht registrieren. Das liegt daran, dass alle IP-Adressen und zugehörigen Hostadressen in einem internen Cache gehalten werden. Eine neue Anfrage wird dann einen Cache-Eintrag liefern, aber zu keiner neuen Anfrage an das Betriebssystem führen. Seit Version 1.4 gibt es eine Möglichkeit, die Lebensdauer einer IP-Adresse auf null zu setzen. Dazu wird die Property network-address.cache.ttl gesetzt. Mehr zu den Netzwerk-Properties bietet wieder die Seite http://tutego.de/go/netproperties.
13.5.3Das Netz ist klasse *
Mit der getAddress()-Methode aus der Klasse InetAddress lässt sich leicht herausfinden, welches Netz die Adresse beschreibt. Für ein Multicast-Socket ist die Internetadresse ein Klasse-D-Netz. Dieses beginnt mit den vier Bits 1110, hexadezimal 0xE0. Folgende Zeilen fragen dies für eine beliebige InetAddress ab:
boolean isDNet = (ia.getAddress()[0] & 0xF0) == 0xE0;
Für den speziellen Fall einer Multicast-Adresse bietet InetAddress auch die Methode isMulticastAddress() an.
13.5.4NetworkInterface
Die Klasse java.net.NetworkInterface repräsentiert eine Netzwerkschnittstelle und mit ihr einen Namen und eine Reihe von IP-Adressen. Mithilfe der Klasse ist es möglich, alle IP-Adressen des lokalen Rechners auszulesen. Das folgende Beispiel soll die Methoden der Klasse demonstrieren:
Listing 13.14com/tutego/insel/net/LocalIpAddress.java, main()
int n = 0;
while ( netInter.hasMoreElements() ) {
NetworkInterface ni = netInter.nextElement();
System.out.println( "NetworkInterface " + n++ + ": " + ni.getDisplayName() );
for ( InetAddress iaddress : Collections.list( ni.getInetAddresses() ) ) {
System.out.println( "CanonicalHostName: " +
iaddress.getCanonicalHostName() );
System.out.println( "IP: " +
iaddress.getHostAddress() );
System.out.println( "Loopback? " +
iaddress.isLoopbackAddress() );
System.out.println( "SiteLocal? " +
iaddress.isSiteLocalAddress() );
System.out.println();
}
}
Auf meinem Rechner, der sich hinter einem Router befindet, ergibt sich:
CanonicalHostName: localhost
IP: 127.0.0.1
Loopback? true
SiteLocal? false
NetworkInterface 1: Intel(R) PRO/1000 PL Network Connection – Paketplaner-Miniport
CanonicalHostName: dell
IP: 192.168.2.138
Loopback? false
SiteLocal? true