Java InetAddress
IP-Adressen in Java mit der InetAddress-Klasse auflösen und darstellen.
Jede Verbindung in diesem Teil benötigte eine Adresse — einen Host und einen Port. java.net.InetAddress ist die Klasse, die den Host-Teil repräsentiert: eine IP-Adresse, optional gepaart mit einem Hostnamen. Sie ist auch das Tor zu DNS (dem Domain Name System), das einen Namen wie example.com in die numerische Adresse umwandelt, an die das Netzwerk tatsächlich weiterleitet. Dieses letzte Networking-Kapitel behandelt das Erstellen, Auflösen und Untersuchen von Adressen. Die InetAddress-Instanzen, die Sie hier erstellen, sind genau die, die Sie an einen Socket, einen ServerSocket oder einen DatagramSocket übergeben, um tatsächlich eine Verbindung herzustellen.
Kein öffentlicher Konstruktor — Factory-Methoden verwenden
Sie schreiben nie new InetAddress(...). Stattdessen:
InetAddress a = InetAddress.getByName("example.com"); // DNS lookup (or parse a literal)
InetAddress b = InetAddress.getByName("93.184.216.34"); // numeric literal: no DNS
InetAddress[] all = InetAddress.getAllByName("example.com"); // every address for a host
InetAddress lo = InetAddress.getLoopbackAddress(); // 127.0.0.1 / ::1, never fails
InetAddress me = InetAddress.getLocalHost(); // this machine's address
InetAddress c = InetAddress.getByAddress(new byte[]{10,0,0,1}); // from raw bytesWesentlicher Unterschied: getByName mit einem Hostnamen führt eine DNS-Abfrage durch (die langsam sein oder offline eine UnknownHostException auslösen kann); mit einem numerischen Literal wird der Wert nur geparst, ohne Netzwerkzugriff. getByAddress erstellt eine Adresse aus rohen Bytes ohne jede Auflösung.
Wann greife ich darauf zurück? Immer dann, wenn Sie einen Namen vor dem Verbinden auflösen müssen, eine Adresse validieren oder klassifizieren möchten (Loopback, privat, Multicast) oder eine gecachte Adresse behalten wollen, um wiederholte DNS-Abfragen in einem Hot Path zu vermeiden. Eine übergeordnete Hilfsklasse wie die URL-Klasse löst Hosts im Hintergrund für Sie auf; InetAddress ist die Schicht, auf die Sie zurückgreifen, wenn Sie die Adresse selbst benötigen.
IPv4 und IPv6
InetAddress ist der gemeinsame Supertyp; konkrete Instanzen sind Inet4Address (32-Bit, 93.184.216.34) oder Inet6Address (128-Bit, ::1). getAddress() gibt die rohen Bytes zurück (4 oder 16), und getHostAddress() gibt die kanonische Textform zurück. Code sollte beide Adressfamilien einheitlich über den Typ InetAddress behandeln.
Eine Adresse untersuchen
Nützliche Prädikate klassifizieren eine Adresse ohne Netzwerkaufruf: isLoopbackAddress(), isSiteLocalAddress() (private Bereiche wie 10.x / 192.168.x), isMulticastAddress(), isAnyLocalAddress() (der Platzhalter 0.0.0.0) und isReachable(timeout) (eine echte Ping-ähnliche Prüfung — die einzige Methode hier, die tatsächlich das Netzwerk kontaktiert).
Ein praktisches Beispiel: Adressen erstellen und klassifizieren
Dieses Programm erstellt Adressen auf verschiedene Arten — Loopback, ein IPv4-Literal, rohe Bytes, ein IPv6-Literal — und untersucht jede mit den Klassifikationsprädikaten. Es verwendet absichtlich Literale und Loopback, damit es offline läuft; der einzige DNS-abhängige Aufruf (getLocalHost) ist geschützt.
Was man aus der Ausführung mitnehmen kann:
- Adressen wurden ohne Konstruktor erstellt — jede Instanz kam von einer Factory:
getLoopbackAddress,getByName,getByAddress. Dieses Design ermöglicht es der JVM, Lookups zu cachen und die richtige Unterklasse (Inet4Addressvs.Inet6Address) für Sie zurückzugeben. getByName("93.184.216.34")undgetByName("::1")haben keine DNS-Abfrage durchgeführt, weil die Argumente numerische Literale waren — die Methode hat sie nur geparst. Derselbe Aufruf mit einem Hostnamen hätte DNS kontaktiert, was der langsame, offline-anfällige Pfad ist; zu wissen, welche Eingaben eine Abfrage auslösen, ist für die Performance wichtig.- Die Anzahl der rohen Bytes unterschied die Adressfamilien: die IPv4-Adresse meldete 4 Bytes, die IPv6-Adresse 16, und
instanceof Inet6Addressbestätigte den konkreten Typ. Code, der Adressen generisch behandelt, arbeitet über den SupertypInetAddressund muss selten nach der Familie verzweigen. - Die Klassifikationsprädikate beantworteten strukturelle Fragen ohne Netzwerkzugriff: die Loopback-Adresse lieferte
truefürisLoopbackAddress(), und die aus Bytes erstellte10.0.0.1liefertetruefürisSiteLocalAddress()(ein privater Bereich). Diese Prüfungen sind reine Arithmetik auf den Adress-Bytes. getLocalHost()war in einem try/catch eingebettet, weil es mitUnknownHostExceptionfehlschlagen kann, wenn der eigene Name des Rechners nicht auflösbar ist. Adressauflösung ist im Wesentlichen eine Netzwerk-/DNS-Operation, die fehlschlagen kann, daher antizipiert robuster Code stets den unaufgelösten Fall — dieselbe Vorsicht, die jedes Kapitel in diesem Teil auf das Netzwerk selbst anwendete.