uio--WebPageMain-Module

JAVA-C3 Network-Programming Network Basics Grundlagen TCP UDP Datagram IP-Adressen Port listen DNS Domain-Name DNS A- und AAAA-Records CNAME-Record Reverse-DNS / PTR-Record TTL Windows: DNS und Host Windows: Firewalls und Ports HTTPS.SYS Nginx als Reverse-Proxy Binding Lokale Netzwerke und NET URI scheme host port path/file Query Fragment / Anchor (01) Hierarchischer URI (02) Opaque URI (03) URI mit Sonderzeichen (04) Normalisierung von URI (04) Normalisierung von URI Prüfen auf Gleichheit a.compare(b) a.equals(b) (05) Relative in absolute URIs übersetzen URL Encoding/Decoding URL-Encoding ASCII Unicode Codepage UTF-8 UTF-16 UTF-32 ISO-8859-1 UTF-32 URLDecoder StandardChartsets.UTF_8

Blocking-I/O Non-Blocking-I/O

network-java-sockets @! network-java-nio FEHLT

Client-Server mit Sockets Unabhängige Java-Programme in Kommunikation über Sockets Client Server @! com.stuelken.java.c1.networking.basics.sockets Version prüfen! @! com.stuelken.java.***.a7.e50200_clientserver_keyvalue.client KeyValueClientResilient class @! Das müssten 3 verschiedene Beispiele/Pages sein! @! Erfordert com.stuelken..ArgumentInterpreter! @! Sprungmarken für Client, Server, .. ergänzen

Overview

Networking | Overview

Bevor man in die Programmierung von Anwendungen stürzt, welche Netzwerk-Verbindungen verwenden, ist es mehr als ratsam, wenn man die wichtigsten Begriffe und Prinzipien wie mitunter TCP, UDP, localhost, Domains, DNS und dergleichen verstanden hat.

Dieser Themenblock umfasst eine kurze Wiederholung zum Thema Netzwerk-Kommunikation und Begriffen, die für die Programmierung von Bedeutung sind.

Basics

Networking | Basics

Netzwerkkommunikation im ISO/OSI Schichtenmodell

Kaum ein Entwickler muss sich ernsthaft mit den Details von TCP oder UDP befassen, denn in der Programmierung von Anwendungen werden üblicherweise auch in Java dann Klassen beispielsweise aus dem Package java.net verwendet, um Verbindungen aufbauen zu können. Für die Wahl der zugehörigen Klassen und das kontrollierte Abfangen von Fehlern ist es aber erforderlich, dass man Prinzip verstanden hat.

Die Liste an Klassen, welche in der Netzwerk- und Web-Programmierung in Java eingesetzt wird, ist doch etwas länger. Netzwerkverbindungen lassen sich mitunter über Klassen aus java.net, wie mitunter java.net.ServerSocket und java.net.Socket verwendet. Das Schreiben und Lesen erfolgte früher über Klassen aus java.io.*, inzwischen auch über java.nio.*.

Die Verwendung von Frameworks, Libraries und dergleichen kann aber dazuführen, dass manche Entwickler gar nicht mehr in den Kontakt mit der eigentlichen Netzwerk-Programmierung kommen, so dass beispielsweise Verbindungen zu einer Datenbank über den Connector erzeugt werden, ohne dass man sich um die Details kümmern muss.

Das Programm, welches die Daten verarbeitet

Netzwerkprogrammierung ist kein Selbstzweck. Der Programmierung geht im Regelfall voraus, dass ein Programm irgendwelche Daten erzeugt hat und versenden möchte.

Alternativ kann es auch sein, dass man gerade eine Anwendung programmiert, in welcher Programmcode auf eine Anfrage wartet, um auf diesem Weg Daten zu bekommen.

Daten im Web laden und Files verschicken

Zu den vermutlich wichtigsten drei Protokollen zählen HTTP (Hypertext Transfer Protocol), FTP (File Transfer Protocol) sowie TELNET.

Verbindungsaufbau

Ein jeder Computer und dessen Programme, welche über Netzwerkverbindungen und Internetverbindungen Daten austauschen möchten, kommunizieren hierbei üblicherweise über TCP (Transmission Control Protocol) oder aber über UDP (User Datagram Protocol).

Damit UDP und TCP funktionieren können, muss eine Verbindung aufgebaut werden zwischen zwei Ports als Anfangs- und Endpunkt einer Verbindung.

IP Layer

Damit TCP oder UDP überhaupt funktionieren können, ist aber die darunter liegende IP Schicht des Netzwerks mit der Auflösung von Domains in IP-Adressen und Ports erforderlich.

Verbindungsaufbau

Dem IP geht wiederum als darunter liegende Schicht voraus, dass dass die Geräte überhaupt einen Link über Netzwerktreiber haben oder schlussendlich irgendwo in Kabel oder eine WLAN-Verbindung besteht.

Mehr erfahren

Wenn Sie mehr zu den Schichten, engl. Layer, erfahren wollen, informieren Sie sich über das ISO/OSI Schichtenmodelle.

Dieses ist zwar zumeist eher ein Tätigkeitsbereich für Systemadministratoren oder Hardwareentwickler, aber wer immer in der Anwendungsprogrammierung nach Fehlerquellen sucht, wird früher oder später verstehen, dass der Fehler tatsächlich in jeder dieser Ebenen liegen kann.

TCP

Kontrollierte Übertragung

Das TCP Transmission Control Protocol ist ein auf Verbindungen, engl. Connection, basierendes Protokoll, welches einen verlässlichen Datenfluss zwischen zwei Rechnern ermöglicht.

Was man im Mindestumfang wissen sollte:

Verbindungsaufbau

Um Daten via TCP zwischen zwei Rechnern austauschen zu können, wird zuerst einmal eine Verbindung aufgebaut.

Die Reihenfolge bleibt erhalten

Egal, wie und auf welche Weise die Datenpakete über TCP tatsächlich zwischen zwei Rechnern vermittelt werden, so hat TCP einen grundlegende Vorteil:

Die Reihenfolge, in welcher Daten vom Versender über TCP verpackt und verschickt werden, ist schlussendlich beim Empfänger die selbe, in welcher dieser Daten dann bekommen wird.

In Fällen, wo das nicht mehr möglich war, wird ein Fehler ausgeworfen.

TCP ist eine Punkt-zu-Punkt-Verbindung

Jede Verbindung basierend auf TCP beginnt an einem Port als Anfangspunkt einer Verbindung und endet auf einem anderen Port als Endpunkt der Verbindung.

TCP ist also eine gute Grundlage für Anwendungen, welche eine verlässliche Kommunikation erfordern.

Hypertext Transfer Protocol

Auch HTTP, das Protokoll, über welches beispielsweise ein Browser als Client mit einem Webserver bei Webseiten oder Webformularen Daten als HTTP Requests verschickt und als HTTP Reponse zurückkommen, setzt wiederum in einer weiteren Schicht auf TCP auf.

Dadurch, dass TCP die Reihenfolge aller verschickten Datenpakete letztendlich sicherstellen kann, ist überhaupt erst garantiert, dass mitunter Formulardaten in der selben Reihenfolge ankommen in welcher diese verschickt werden.

File Transfer Protocol

Eine Vielzahl von Dateien wird zwischen zwei Rechnern zum Server über FTP verschickt beziehungsweise SFTP für die gesicherte Verbindung.

Auch bei FTP ist es von Bedeutung, dass die Kommunikation auch über die Kommunikationskanäle weiterhin in der selben Reihenfolge ankommt wie diese verschickt wurde.



UDP

User Datagram

User Datagramme sind mitunter bekannt durch den ping Befehl.

Was man im Mindestumfang wissen sollte:

Das User Datagram Protocol

UDP unterscheidet sich von TCP maßgeblich darin, dass bei UDP der Empfang von Datagrammen und damit Datenpaketen NICHT garantiert wird.

Datagramme

Die Datenpakete, die via UDP verschickt werden, bezeichnet man als Datagramme, engl. Datagram(s).

Man kann Sie vom Prinzip her mit einem «Brief» im herkömmlichen Postversand vergleichen. Man definiert ein Ziel, schickt die Daten ab, und das war's.

UDP unterscheidet sich von TCP maßgeblich darin, dass bei UDP der Empfang von Datagrammen und damit Datenpaketen NICHT garantiert wird.

Ohne Garantie der Reihenfolge

Die verschickten Datagramme bei UDP werden in der einen Reihenfolge verschickt, könnten aber in einer völlig anderen Reihenfolge unabhängig voneinander ankommen.

Unabhängigkeit von Paketen

Während bei TCP die Verbindung zwischen Sender und Empfänger erhalten wird, ist es bei UDP anders.

Die Daten werden nur verschickt. Auf eine Antwort wird gar nicht gewartet.

UDP: viele Pakete senden und mit Verlusten leben

Bei UDP basiert das Prinzip wie beispielsweise bei einem PING eines anderen Rechners darin, dass lieber mehrere Datenpakete als Datagramme sendet, den Verlust von Paketen aber akzeptiert.

Wenn also nur darum geht, um prüfen zu können, ob ein anderer Rechner überhaupt noch verfügbar ist oder man quasi einen Status herumschickt, ohne dass es einen interessiert, ob das nun jeder gerade bekommen hat, ist UDP denkbar.


UDP wird in vielen Firewalls inzwischen konsequent geblockt, dh. Firewalls können zwischen TCP und UDP Paketen differenzieren. TCP ist unerlässlich beim Aufbauen von Verbindungen. Da man die Daten, die man per UDP verschickt, auch in TCP hätte verpacken können, ist das für Entwickler einer Anwendung auch kein großes Problem.


Gaming: Im Spielebereich macht z. T. UDP wieder einen Sinn, so dass man ggf. mal die Firewall konfigurieren muss.

IP und Port

Authority-Parameter von URIs und URLs

Im Regelfall hat jeder Rechner nur eine Verbindung mit dem Netzwerk, dh. alles, was man versenden oder empfangen muss, muss letztendlich hier vermittelt werden. Damit man bei jedem Datenpaket wissen kann, zu welcher Programmanwendung es eigentlich gehört, hat man die sogenannten Ports als Anfangs- und Endpunkt einer Verbindung geschaffen.

URIs und URLs in Java kombinieren das wahlweise als uri.getAuthority()-Parameter oder auch separat als uri.getHost() und uri.getPort().

InetSocketAddress addr = new InetSocketAddress(host, port): Die Kombination von IP-Adresse und Port findet sich mitunter in der Definition von Internet-Socket-Adressen in Java, wobei der host die IP-Adresse enthalten kann, wobei dort zumeist eine Domain steht.

Was man im Mindestumfang wissen sollte:

localhost:6000, 127.0.0.1:6000, example.com

Um über Netzwerkverbindungen Daten von einer Anwendung des einen Rechners an eine andere Anwendung auf dem selben oder einen anderen Rechner verschicken zu können, muss man primär zwei Dinge kennen:

Man benötigt die IP-Adressen oder aber zumindest die Domain. Die lokale IP-Adresse eines Rechners, auch als Loopback-Adapter bezeichnet, lautet als Domain localhost und als IP-Adresse im IPv4 Format dann 127.0.0.1.

Gefolgt nach einem : folgt dann der zugehörige Port wie beispielsweise Port 6000

Computer werden über 32-bit-IP-Adressen addressiert

Das entspricht 2 hoch 32 Adressen abzüglich derer, die aus anderen Gründen gesperrt sind wie mitunter die 127.0.0.1.

Die Anzahl von Ports wird über 16-bit beschränkt

Die maximale Anzahl von Ports auf einem Rechner bzw. seiner Netzwerkkarte liegt also bei 2 hoch 16 Ports, damit via TCP oder IP eine Verbindung aufgenommen werden kann.

Reservieren von Ports

Um eine TCP Verbindung, engl. Connection, aufbauen zu können, verbindet sich eine Programmanwendung auf dem Server über einen Socket auf einem bestimmten Port.

Normalerweise ist es nun so, dass nur dieses eine Programm diesen Port reserviert hat und damit jedes andere Programm, welches als dann «Client» mit diesem «Server» auf diesem Port Kontakt aufnimmt, die Daten auch genau über diesen Socket an dieses eine Programm sendet.

Wichtige Standardports sollten vermieden werden.

Eine Reihe von Ports zwischen 0 und 1023 sind weltweit für bestimmte Protokolle wie beispielweise Port 80 für HTTP, Port 443 für HTTS und dergleichen beschränkt.

Es ist zwar technisch zuweilen möglich, dass Ihr Programm diese Ports dennoch verwendet und damit zweckentwendet, aber das Risiko, dass hierbei Probleme entstehen werden, ist doch höher.

Man muss hierzu nun noch wissen, dass Firewalls üblicherweise den Netzwerkverkehr nur für bestimmte Ports und Typen von Datenpaketen zulassen.

Domainnamen lassen sich mit IP-Adressen verbinden

Domainnamen dienen primär dem Zweck, damit man Rechner oder Services darauf immer mit der gleichen Adresse und damit dem URL Objekt adressieren kann, auch dann, wenn sich mal die IP-Adresse verändert.

Wenn ein Programm den Rechner nicht finden kann.

Um die Namensauflösung von Domainnamen wie example.com oder auch localhost oder wasauchimmer kümmern sich mitunter Administratoren im Netzwerk oder rund um die Thematik des Webhostings, doch es gibt Ausnahmen:

So können oder auch müssen für Anwendungen auf dem eigenen Rechner zuweilen virtuelle Hosts eingetragen werden, so dass man beispielsweise auch eine im Internet schon belegte Domain auch lokal angelegen kann, so dass Zugriffe auf diese Domain nicht mehr für den Zugriff ins Internet erfolgen sondern auf eine lokale Ressource.

DNS

Namensauflösung und DNS

Um von einem Domainnamen auf eine IP-Adresse schließen können, muss der zugehörige Domainname der Name aufgelöst werden.

Diese Auflösung des host-Namen in einem URI oder einem URI hat mit Java Programmierung nur am Rande zu tun, denn die Namensauflösung erfolgt über mehrere Schritte.

Was man im Mindestumfang wissen sollte:

Domain-Name / Hostname

Ein Domain-Name oder Hostname ist ein menschen­lesbarer Alias, unter dem ein Rechner im Netz erreichbar ist (z. B. example.com statt 93.184.216.34).

In Java kann man ihn mit InetAddress.getHostName() erfragen.

DNS (Domain Name System)

DNS ist das verteilte System, das Hostnamen in IP-Adressen (und umgekehrt) übersetzt. Java nutzt intern das Betriebssystem oder native Libraries (über JNI) für die DNS-Auflösung, kann aber kein eigenes DNS-Protokoll „out of the box“ implementieren.

A- und AAAA-Records

Ein A-Record verknüpft einen Hostnamen mit einer IPv4-Adresse, ein AAAA-Record mit einer IPv6-Adresse. Die Time-to-Live-Angabe (TTL) legt fest, wie lange diese Information im Cache bleibt.

CNAME-Record

Ein CNAME (Canonical Name) definiert einen Alias für einen anderen Hostnamen. DNS-Server leiten bei der Auflösung automatisch auf den kanonischen Namen weiter.

Reverse DNS / PTR-Record

Ein PTR-Record verbindet eine IP-Adresse mit einem Hostnamen (umgekehrte Auflösung), z. B. für E-Mail-Server.

In Java kann man ihn mit InetAddress.getHostName() erfragen.

TTL (Time to Live)

Die TTL-Angabe in einem DNS-Record steuert, wie lange Ergebnisse im Cache gespeichert bleiben. Kurze TTLs führen zu häufigeren DNS-Anfragen, lange TTLs reduzieren die Last auf den Nameservern.

Domain-Name / Hostname

In Produktivumgebungen hängt der Hostname an richtigen DNS-Records. Bei einer lokalen Umgebung muss man unter Windows aber ggf. die WIndows-Hosts-Datei editieren:

File: \Windows\System32\drivers\etc\hosts

Dort lässt sich example.local 127.0.0.1 auf 127.0.0.1 mappen.

Standard-Windows-Firewall blockiert eingehende TCP-Verbindungen.

Um überhaupt auf einem PC von einem anderen PC im lokalen Netzwerk Verbindungen annehmen zu können, müssen für HTTP und HTTPS die Ports 80 und 443 geöffnet werden.

netsh advfirewall firewall add rule name="HTTP" dir=in action=allow protocol=TCP localport=80

all add rule name="HTTPS" dir=in action=allow protocol=TCP localport=443

Für nicht-privilegierte Ports mit einer Portnummer größer oder gleich 1024 sind KEINE Admin-Rechte erforderlich. In den anderen Fällen muss man Dienste als Admin starten oder die URL eines Service mit HTTP.SYS reserverieren.

Für Java-Anwendungen wie Servlets und JSP hat man einst früher den Port 8080 verwendet; dieser liegt über 1024.

com.sun.net.httpserver.HttpServer und HttpListener

Um mit Java mit HttpListener auf einem Port lauschen zu können oder aber den mit Java ausgelieferten eigenen HttpServer verwenden zu können, muss man sicherstellen, dass Windows einem die Reservierung über HTTP.SYS-URLs ermöglicht.

netsh http add urlacl url=http://+:8080/ user="DOMAIN\benutzer" listen=yes

com.sun.net.httpserver.HttpServer wird mit Java ausgeliefert und darf als Grundlage für eigene Webanwendungen verwendet werden, auch wenn com.sun.net als Package-Name den Eindruck erweckt, dass es ggf. geschützt sein könnte.

Wenn der Datenverkehr über Proxies läuft

In Fällen, in welchen der Datenverkehr nicht direkt sondern über Proxies läuft, benötigt man einen Reverse-Proxy.

Unter Windows kann man mitunter den IIS Internet Information Server mit einem speziellen Modul verwenden. Im Internet nutzt man für Webhosting von Webseiten und Webservices aber zumeist Nginx.

Wie man Nginx unter Windows oder Linux konfiguriert, ist nicht Inhalt dieser Einführung.

Das Binding eines Webservices an IPs und Domains

Header X-Forwarded-For, X-Forwared-Host, X-Forwared-Proto

Network Address Translation

Wenn man sich in einem Firmennetz oder Heimnetz beispielsweise hinter einem DSL-Router, den viele Menschen inzwischen nur noch als FritzBox kennen, oder einem anderen Router befindet, müssen die Adressen und Ports, die von außen adressiert wurden, auf die eigentlichen IPs und Ports innerhalb des über den Router abgesicherten Netzwerks «übersetzt» werden. Das bezeichnet man als Network Address Translation, kurz NAT.

Warum ein Proxy vor eurem ServerSocket?

Ein Reverse-Proxy läuft als eigener Dienst zwischen Router und eurer Java-App. Er terminiert TLS, verteilt Last (Load-Balancing), cached Inhalte und schützt die Backends.

Technisch empfängt NGINX die HTTP-Anfrage, liest Host-Header und Pfad und leitet sie per TCP oder HTTP an den internen ServerSocket weiter (z.B. localhost:8080).

Eure Java-App sieht nur eine „lokale“ Verbindung – um dennoch den echten Client zu erkennen, setzt der Proxy Header:

// in Java (Sun HTTP-Server oder Servlet-API) String clientIp = exchange.getRequestHeaders() .getFirst("X-Forwarded-For"); String scheme = exchange.getRequestHeaders() .getFirst("X-Forwarded-Proto");

So könnt ihr in Logs, URLs oder Sicherheitsregeln den ursprünglichen Client-IP, das Host-Mapping und Protokoll korrekt abrufen.

Das Binding eines ServerSockets

Binding reserviert einen Port und eine lokale Adresse, auf der euer ServerSocket lauscht. Ohne explizites Binding nutzt Java die Wildcard-Adresse (0.0.0.0) und einen dynamischen Port.

Bindet ihr z. B. an 127.0.0.1, sind nur lokale Clients zugelassen. Für alle Interfaces wählt 0.0.0.0.

// bindet auf Port 8080 für alle Interfaces ServerSocket server = new ServerSocket(8080, 50, InetAddress.getByName("0.0.0.0"));

Was NAT leistet (und was nicht)

NAT übersetzt IP-Adressen und Ports auf OSI-Schicht 3/4: Externe Anfragen an eure öffentliche IP werden im Router auf die private IP/den Port eures Servers weitergeleitet.

Anders als ein Proxy ändert NAT nicht den HTTP-Header oder Inhalt – es manipuliert nur IP- und TCP/UDP-Felder. Eure Java-App ist sich dessen nicht bewusst und erhält eine “normale” Verbindung.

Java Klassen für Netzwerkverbindungen

Es gibt eine Reihe von Klassen in Java, die jeder Entwickler schon mal gehört haben sollte, wenn es um die Thematik einer Kommunikation über Netzwerk- oder Internetverbindungen geht.

Was man im Mindestumfang wissen sollte:

java.net ermöglicht UDP/TCP Verbindungen im Netzwerk

Uniform Ressource Locator oder aber Java Klasse

Der URL Uniform Ressource Locator umfasst alle Informationen zu einer Zieladresse mit Protokoll, IP-Adresse, Port, URI und damit zuweilen im Falle von HTTP auch GET-Parametern.


In JAVA steht URL zuerst einmal für die Klasse und damit den Typ von Objekten.


localhost:6000 ist also eine Adresse auf einem Server ohne Angabe des Protokolls, während hingegen http://localhost:8080 die Domain und damit via Namensauflösung die IP-Adresse mit dem Port adressiert, hierbei die Daten aber dann im HTTP Protokoll verpacken will.

http:// bezeichnet man als Bezeichner für das Protokoll, englisch «protocol identifier».

localhost bezeichnet man hierbei als Name der Ressource, auch oft als Hostname bezeichnet.

Mit #sprungmarke kann mitunter zuweilen noch ein benannter Anchor beispielsweise bei HTTP angegeben werden, so dass nicht nur ein File-Name adressiert werden kann sondern auch die Sprungmarke in einem HTML Dokument.

Ein- und Ausgehende Verbindungen

Ein Socket auf einem Port für eine IP-Adresse stellt sicher, dass eingehende Verbindungen vom ServerSocket akzeptiert werden können, für die weitere Verbindung aber dann ein neuer Socket erzeugt wird, über welchen die eigentliche Kommunikation mit dem Client dann fortgesetzt wird.

Links

Quellen, Notes, Tags


    UI ORGANIZED.

    UIO3 Es ist einfacher als Du denkst.

    Stelle noch heute Deine Anfrage.

    uio--WebPageFooter-Module