Vorlesung 1
Netzwerkkommunikation und serverseitige Technologien

In der Zukunft der Netzwerkkommunikation und serverseitigen Technologien erwarten uns bahnbrechende Entwicklungen, die die Art und Weise, wie wir Daten verarbeiten und teilen, neu definieren werden. Mit der Einführung von 5G-Netzwerken werden wir eine signifikante Beschleunigung der Geschwindigkeit und Verringerung der Latenz erleben, was neue Möglichkeiten für IoT und Echtzeitanwendungen eröffnet. Edge Computing wird die Datenverarbeitung näher an den Endnutzer bringen, was zu schnelleren und effizienteren Netzwerkdiensten führt. Serverlose Architekturen und die Integration von KI und maschinellem Lernen in serverseitige Prozesse werden die Entwicklung agiler und intelligenter Anwendungen vorantreiben. Gleichzeitig wird der Fokus auf Sicherheit und Datenschutz stärker denn je, während Nachhaltigkeitsinitiativen die ökologische Auswirkung der Technologiebranche zunehmend in den Vordergrund rücken. Diese Trends skizzieren eine aufregende Zukunft, in der Technologie weiterhin die Grenzen dessen verschiebt, was möglich ist.

Client-Server Modell

In der Welt der Computernetzwerke bezieht sich die Kommunikation und Verteilung von Programmen und Funktionalitäten zwischen zwei Rechnern oft auf das Client-Server-Modell. In diesem Modell interagieren zwei Arten von Computern: der Client und der Server. Jeder hat seine eigene Rolle und Funktion im Netzwerk.

Der Client

Der Client ist in der Regel der Computer, der einen Dienst oder Ressourcen anfordert. Dies kann ein Desktop-Computer, ein Laptop, ein Smartphone oder jedes andere Gerät mit Netzwerkzugang sein. Clients sind oft schwächer, langsamer oder kleiner im Vergleich zu Servern. Das bedeutet, sie haben möglicherweise weniger Rechenleistung, Speicher oder Speicherkapazität. Clients initiieren in der Regel die Kommunikation mit dem Server, indem sie Anfragen senden.

Der Server (Host)

Auf der anderen Seite steht der Server, ein leistungsstarker Computer, der Ressourcen oder Dienste zur Verfügung stellt. Server sind in der Regel mit leistungsstärkeren Prozessoren, mehr Speicher und größeren Speicherkapazitäten ausgestattet, um mehrere Anfragen gleichzeitig bedienen zu können. Sie sind größer, stärker und schneller im Vergleich zu den Clients, weil sie darauf ausgelegt sind, gleichzeitig mehrere Anfragen zu bearbeiten und auf diese schnell zu reagieren.

Kommunikation und Verteilung von Funktionalitäten:

  • Anfrage-Antwort-Modell In einem typischen Client-Server-Modell sendet der Client eine Anfrage an den Server, der daraufhin eine Antwort zurücksendet. Zum Beispiel könnte ein Webbrowser (Client) eine Anfrage an einen Webserver senden, um eine Webseite abzurufen. Der Server verarbeitet die Anfrage und sendet die entsprechenden Daten zurück an den Client.
  • RessourcenteilungServer können viele Arten von Ressourcen wie Dateien, Datenbanken, Netzwerkdienste und mehr anbieten. Clients greifen auf diese Ressourcen zu, um bestimmte Aufgaben zu erfüllen, ohne alle notwendigen Daten oder Anwendungen lokal speichern oder ausführen zu müssen.
  • DezentralisierungDurch die Verteilung von Funktionalitäten zwischen Clients und Servern können Netzwerke effizienter gestaltet werden. Clients müssen nicht übermäßig leistungsstark sein, da sie auf die Verarbeitungsleistung des Servers zugreifen können.
  • SkalierbarkeitEin leistungsstarker Server kann viele Clients bedienen, was die Skalierbarkeit des Systems erhöht. Wenn die Anzahl der Benutzer oder die Anforderungen an die Ressourcen wachsen, können Server hinzugefügt oder aufgerüstet werden, um den Bedarf zu decken.

Das Client-Server-Modell ist ein grundlegendes Konzept in der Computernetzwerkarchitektur und bildet die Basis für viele Arten von Netzwerkanwendungen und -diensten.

Ethernet zu Beginn: Historie

Ethernet ist eine grundlegende Technologie, die seit den frühen 1970er Jahren die Grundlage für lokale Netzwerke (LANs) bildet. Die Anfänge von Ethernet können auf das Forschungslabor von Xerox PARC zurückgeführt werden, wo es von Robert Metcalfe und seinem Team entwickelt wurde. Die ursprüngliche Konzeption von Ethernet basierte auf der Idee, dass mehrere Computer über ein einziges Koaxialkabel kommunizieren können, das als gemeinsames Übertragungsmedium dient.

Koax Kabel

Das Koaxialkabel, das in den frühen Ethernet-Netzwerken verwendet wurde, spielte eine zentrale Rolle bei der Übertragung von Daten zwischen Computern. Dieses Kabel ist so konstruiert, dass es einen zentralen, leitenden Kern besitzt, der von einem isolierenden Dielektrikum umgeben ist. Über dem Dielektrikum befindet sich eine metallische Abschirmung, die wiederum von einer äußeren Schicht umhüllt wird. Diese Konstruktion ermöglicht eine robuste und störungsarme Signalübertragung.

In den Anfängen von Ethernet wurde ein spezifisches Koaxialkabel, bekannt als Thicknet (10BASE5), eingesetzt. Dieses Kabel war relativ steif und schwer zu handhaben, bot aber die nötige Zuverlässigkeit für die damaligen Netzwerke. Später wurde ein dünneres und flexibleres Koaxialkabel, Thinnet (10BASE2), eingeführt, das einfacher zu installieren war.

Kollisionen

Im Kontext von Ethernet-Netzwerken, die auf Koaxialkabeln basierten, bezieht sich eine Kollision auf ein Ereignis, bei dem zwei Geräte gleichzeitig Daten über das gleiche Kabel senden. Da das Kabel ein gemeinsames Medium war, führten solche gleichzeitigen Übertragungen zu Dateninterferenzen. Das CSMA/CD-Protokoll (Carrier Sense Multiple Access with Collision Detection) wurde entwickelt, um dieses Problem zu bewältigen. Geräte prüfen, ob das Kabel frei ist, bevor sie senden, und warten im Falle einer Kollision eine zufällige Zeitspanne, bevor sie es erneut versuchen.

Entwicklung zur Kollisionsvermeidung

  • Von Koaxialkabeln zu Twisted-Pair- und Glasfaserkabeln
    Die Einführung von Twisted-Pair-Kabeln (wie 10BASE-T) und später Glasfaserkabeln bot dedizierte Verbindungen zwischen einzelnen Geräten und einem zentralen Netzwerkgerät (z.B. einem Switch), was Kollisionen auf dem Übertragungsmedium eliminieren konnte.

  • Switches statt Hubs
    Die Verwendung von Netzwerkswitches anstelle von Hubs bedeutete, dass Datenpakete direkt an das Zielgerät gesendet werden konnten, anstatt wie bei einem Hub an alle Geräte. Dies reduzierte die Wahrscheinlichkeit von Kollisionen erheblich, da Switches dedizierte Pfade für die Kommunikation zwischen jedem Gerätepaar erstellen.

  • Full-Duplex-Übertragung
    Moderne Ethernet-Netzwerke können im Full-Duplex-Modus betrieben werden, was bedeutet, dass Geräte gleichzeitig senden und empfangen können, ohne Kollisionen befürchten zu müssen. Dies wird durch die Verwendung von getrennten Kanälen für sendende und empfangende Daten ermöglicht, wie es bei der Verbindung von Computern zu Switches der Fall ist.

Diese Entwicklungen haben dazu geführt, dass Koaxialkabel-basierte Ethernet-Netzwerke mit ihren inhärenten Kollisionsproblemen weitgehend durch effizientere, kollisionsfreie Netzwerkinfrastrukturen ersetzt wurden.

Das Kommunikationsmodell

Das 5-Tupel-Modell ist eine präzise Methode, um eine Netzwerkverbindung zu charakterisieren, speziell in Kontexten wie TCP/IP, wo es um die Verbindung zwischen einem Webserver und einem Client geht. Das 5-Tupel besteht aus:

  1. Protokoll
    Dies gibt das Kommunikationsprotokoll an, das für die Übertragung verwendet wird. In Ihrem Beispiel ist dies TCP (Transmission Control Protocol), das für die zuverlässige Übertragung von Datenpaketen im Internet sorgt. TCP ist ein verbindungsorientiertes Protokoll, das einen Handshake-Prozess verwendet, um eine sichere Verbindung zwischen Sender und Empfänger zu etablieren.

  2. Lokaler Host (IP-Nummer des lokalen Hosts)
    Dies ist die IP-Adresse des Geräts, von dem die Verbindung initiiert wird oder auf dem die Anfrage empfangen wird. In Ihrem Beispiel ist 196.8.79.22 die IP-Adresse des lokalen Hosts, also beispielsweise des Webservers.

  3. Lokaler Prozess (Portnummer lokaler Host)
    Hier wird der spezifische Prozess auf dem lokalen Host identifiziert, in der Regel durch eine Portnummer. Im Beispiel ist 1078 die Portnummer auf dem lokalen Host, die den spezifischen Prozess (z.B. eine bestimmte Instanz eines Webdienstes) kennzeichnet, mit dem kommuniziert wird.

  4. Fremder Host (IP-Nummer des fremden Hosts):
    Dies ist die IP-Adresse des Zielgeräts in der Kommunikation, also des Geräts, das die Daten anfordert oder an das die Daten gesendet werden. In diesem Fall ist 132.49.2.3 die IP-Adresse des fremden Hosts.

  5. Fremder Prozess (Portnummer fremder Host):
    Ähnlich wie beim lokalen Prozess identifiziert dies den spezifischen Prozess auf dem Zielgerät, der über eine Portnummer (21 in als Beispiel) spezifiziert wird. Port 21 wird oft für FTP verwendet, aber in einem Webkontext könnte dies auch für HTTP (Port 80) oder HTTPS (Port 443) stehen, je nachdem, welcher Dienst angefordert wird.

Software-Architektur von dynamischen Web-Seiten

Die Software-Architektur von dynamischen Webseiten umfasst sowohl clientseitige als auch serverseitige Komponenten, die interaktiv zusammenarbeiten, um eine reaktionsfähige und interaktive Benutzererfahrung zu ermöglichen. Im Gegensatz zu statischen Webseiten, die festen Inhalt liefern, können dynamische Webseiten ihren Inhalt in Echtzeit anpassen, basierend auf Interaktionen des Benutzers oder anderen Faktoren.

Serverseitige Architektur

Auf der Serverseite werden dynamische Webseiten oft mit Hilfe von Programmiersprachen wie PHP, Python, Ruby oder JavaScript (Node.js) entwickelt. Diese serverseitigen Skripte interagieren mit Datenbanken, Dateisystemen und anderen Ressourcen, um Inhalte zu generieren, die an den Client gesendet werden.

  • Datenverarbeitung
    Serverseitige Skripte verarbeiten Anfragen vom Client, führen Geschäftslogik aus, interagieren mit Datenbanken und erzeugen die erforderlichen Daten.

  • Dynamische Inhaltserstellung
    Anstatt eine fixe HTML-Seite zu senden, generieren serverseitige Skripte dynamisch HTML, CSS und JavaScript basierend auf der aktuellen Anfrage, Benutzerinteraktionen oder anderen Parametern.

  • Datenbankinteraktion
    Dynamische Webseiten interagieren häufig mit Datenbanken, um Inhalte zu speichern und abzurufen. Dies ermöglicht eine personalisierte Benutzererfahrung und die Fähigkeit, große Mengen von Daten effektiv zu verwalten.

Clientseitige Architektur

Auf der Clientseite wird das dynamische Verhalten durch JavaScript, zusammen mit HTML und CSS, ermöglicht. Moderne Webanwendungen nutzen oft JavaScript-Frameworks oder -Bibliotheken wie React, Angular oder Vue.js, um interaktive Benutzeroberflächen zu erstellen.

  • Dynamische InteraktionJavaScript ermöglicht es, auf Benutzerinteraktionen zu reagieren, ohne notwendigerweise mit dem Server kommunizieren zu müssen. Dies umfasst Aktionen wie das Erweitern eines Dropdown-Menüs oder das Überprüfen von Formulareingaben.
  • Asynchrone AnfragenMit AJAX (Asynchronous JavaScript and XML) können Webseiten asynchron Daten mit dem Server austauschen und Teile der Seite aktualisieren, ohne die Seite neu laden zu müssen.
  • Clientseitige Manipulation des DOMavaScript kann das Document Object Model (DOM) manipulieren, was die Modifikation von Elementen und Inhalten auf einer Seite in Echtzeit ermöglicht.

Zusammenspiel von Client und Server

In einer dynamischen Webseite interagieren die clientseitigen und serverseitigen Komponenten miteinander, um eine reaktive Benutzererfahrung zu ermöglichen:

  • Der Benutzer interagiert mit der Webseite im Browser (Clientseite).
  • JavaScript fängt diese Interaktionen ab und kann entweder direkt auf der Clientseite reagieren oder eine Anfrage an den Server senden.
  • Der Server verarbeitet die Anfrage (z.B. Datenabfrage, Geschäftslogik) und sendet eine Antwort zurück.
  • Die Antwort wird clientseitig verarbeitet, oft durch Aktualisieren des DOM, um neue oder veränderte Inhalte anzuzeigen, ohne die Seite vollständig neu zu laden.

Durch diese Kombination von Technologien können dynamische Webseiten komplexe und interaktive Benutzererlebnisse bieten, die weit über die Möglichkeiten statischer Seiten hinausgehen.

Einführung in clientseitige Technologien

Diese Technologien laufen direkt im Browser des Benutzers ab und sind entscheidend für die Interaktivität und Benutzererfahrung auf Webseiten.

  • JavaScript & FrameworksWird für interaktive Elemente auf der Clientseite verwendet.

  • Java AppletsFrüher genutzt zur Erweiterung der Browserfunktionalität, heute jedoch wegen Sicherheitsbedenken und veralteter Technik kaum noch verwendet.

  • Native AppsEntwicklung spezifisch für iOS (Swift) und Android (Java).

  • Hybride/Web-AppsServerseitig programmierte Anwendungen, die auf das Endgerät native Code oder JavaScript für den Browser ausliefern.

Überblick über serverseitige Technologien

Serverseitige Technologien sind für die Datenverarbeitung, Logik und das Backend-Management von Webanwendungen verantwortlich.

  • CGI (Common Gateway Interface)Einmal weit verbreitet, jetzt wegen Performance- und Sicherheitsproblemen veraltet.

  • PHPEine populäre Scriptsprache für serverseitige Entwicklung, unterstützt durch umfangreiche Funktionen und einfache Erlernbarkeit. Verbesserungen in der Performance wurden durch JIT-Kompilierung erreicht.

  • Java Servlets & JSPJava-Technologien zur Erzeugung dynamischer Webinhalte, wobei Servlets die Basis für JSP bilden.

  • Node.jsEine Plattform, die JavaScript auf dem Server ausführt, unterstützt durch ein umfangreiches Paketökosystem (npm).

Spezielle Entwicklungen und Trends

Dieser Abschnitt beleuchtet die Verschiebung von veralteten Technologien zu modernen Ansätzen in der Webentwicklung.

  • Veraltete Technologien: Die Abkehr von älteren Technologien wie Java Applets und CGI zugunsten modernerer Lösungen.
  • Moderne Praktiken: Einsatz von Node.js für serverseitiges JavaScript und die Nutzung von PHP für dynamische Webseitenerzeugung und Datenbankinteraktionen.

Streams, Serialisierung und und Datei Datei E/A

Speicherung von Zuständen

Objekte in der Programmierung können sowohl einen Zustand als auch ein Verhalten haben. Während das Verhalten in der Klasse definiert ist, ist der Zustand individuell für jedes Objekt. Die Speicherung dieses Zustands ist wesentlich, um beispielsweise den Fortschritt in einem Spiel oder die Daten in einer Anwendung, die Diagramme erzeugt, zu erhalten. Es werden zwei Methoden zur Speicherung von Objektzuständen vorgestellt: eine manuelle Methode, bei der der Entwickler den Zustand jedes Objekts einzeln erfasst und speichert, und eine objektorientierte Methode, die die Serialisierung von Objekten nutzt, um ihren Zustand effizient zu speichern und wiederherzustellen. Die Wahl der Methode kann abhängen von der Notwendigkeit, die gespeicherten Daten mit Nicht-Java-Programmen zu teilen, was die manuelle Methode erfordern könnte.

Objektzustände und Persistenz in Java

In Java kann der Zustand eines Objekts für verschiedene Zwecke wie Datensicherung, Netzwerkübertragung oder einfach zur späteren Verwendung gespeichert werden. Dies ist besonders nützlich in Anwendungen, bei denen der Zustand eines Objekts über einen gewissen Zeitraum hinweg konsistent bleiben muss, wie bei Online-Spielen, E-Commerce-Transaktionen oder jeder Art von Anwendung, die eine Sitzungsverwaltung erfordert.

Beispiel für die Spielfigurenspeicherung: Betrachten Sie ein Rollenspiel, bei dem die Attribute einer Spielfigur wie Gesundheit, Mana und Inventar gespeichert werden müssen. Wenn der Spieler das Spiel verlässt und später zurückkehrt, erwartet er, dass seine Spielfigur in demselben Zustand ist, in dem er sie verlassen hat.

Tiefgreifender Blick auf Serialisierung und Deserialisierung

Serialisierung in Java ist ein Mechanismus, bei dem ein Objekt in eine Bytefolge umgewandelt wird, die dann leicht in Dateien gespeichert oder über Netzwerke übertragen werden kann. Deserialisierung ist der umgekehrte Prozess, bei dem aus der Bytefolge wieder ein Objekt rekonstruiert wird.

Details zur Serialisierbarkeit: Ein Objekt muss das Serializable-Interface implementieren, um serialisierbar zu sein. Es ist wichtig zu beachten, dass nicht alle Objekte serialisiert werden können, insbesondere solche, die eine direkte oder indirekte Verbindung zu Systemressourcen haben.

Erweitertes Beispiel zur Serialisierung: Nehmen Sie an, Sie entwickeln eine Client-Server-Anwendung, in der der Client den Zustand eines Benutzerobjekts an den Server senden muss. Die Serialisierung ermöglicht es dem Client, das Benutzerobjekt in einen Byte-Stream umzuwandeln, über das Netzwerk zu senden und vom Server wieder in ein Objekt zu deserialisieren.

Umfassende Betrachtung von Streams in Java

Streams in Java sind eine zentrale Abstraktion für Ein- und Ausgabeoperationen. Sie ermöglichen es Programmen, auf eine abstrahierte Weise mit Datenquellen oder -zielen zu interagieren, sei es eine Datei, ein Netzwerksocket oder sogar der Speicher.

Beispiel für Stream-Verkettung: Beim Lesen von Daten aus einer Datei und deren Umwandlung in Großbuchstaben bevor die Ausgabe auf der Konsole erfolgt, können Streams verkettet werden, um den FileInputStream mit einem InputStreamReader und einem BufferedReader zu kombinieren, wodurch die Effizienz der I/O-Operationen erhöht wird.

Datei-Ein- und Ausgabe in der Praxis

Java bietet eine robuste API für Datei-E/A, mit der Entwickler Daten lesen und schreiben können. Dies ist essentiell für die Persistenz von Daten, insbesondere in verteilten Systemen.

Beispiel zur Dateiverarbeitung: Ein Programm könnte konzipiert sein, um Log-Daten zu verarbeiten. Hierfür liest es kontinuierlich eine Datei, verarbeitet jede Zeile, um bestimmte Informationen zu extrahieren, und schreibt die Ergebnisse in eine andere Datei.

Erweiterte Beispiele und Anwendungsfälle

Serialisierung in verteilten Systemen: In einem verteilten Banksystem könnte ein Objekt, das eine Transaktion darstellt, zwischen verschiedenen Servern übertragen werden müssen. Die Serialisierung ermöglicht es, das Transaktionsobjekt in einen Byte-Stream umzuwandeln, über das Netzwerk zu senden und auf dem Zielserver wieder in ein Objekt zu deserialisieren.

Stream-Manipulation für Datenverarbeitung: Ein Programm, das große Datenmengen verarbeitet, wie beispielsweise ein ETL-Prozess (Extract, Transform, Load), nutzt Streams, um Daten aus einer Quelle zu extrahieren, zu transformieren und in ein neues Format oder Ziel zu laden.

Ein serialisiertes Objekt in eine Datei schreiben

  • Einen FileOutputStream erzeugen
    
    FileOutputStream fileStream = new FileOutputStream("MeinSpiel.ser");
                        

  • Einen ObjectOutputStream erzeugen
    
    ObjectOutputStream os = new ObjectOutputStream(fileStream);
                          

  • Das Objekt schreiben
    
    os.writeObject(figur1);
    os.writeObject(figur2);
    os.writeObject(figur3);
                          

  • Den ObjectOutputStream schließen
    
    os.close();
                          

Deserialisierung: Wiederherstellung eines Objekts

Die Kernidee der Objektserialisierung ist es, ein Objekt in einen Zustand zu versetzen, in dem es gespeichert und später, möglicherweise in einer anderen Instanz der Java Virtual Machine (JVM), in seinen ursprünglichen Zustand zurückversetzt werden kann. Die Deserialisierung funktioniert als Gegenstück zur Serialisierung und stellt das Objekt aus dem gespeicherten Zustand wieder her, was als umgekehrte Serialisierung betrachtet werden kann.

  • Einen File InputStream erzeugen
    
    FileInputStream fileStream = new FileInputStream("MeinSpiel.ser");
                        

  • Einen ObjectInputStream erzeugen
    
    ObjectInputStream os = new ObjectInputStream(fileStream);
                          

  • Das Objekt lesen
    
    Object eins = os.readObject();
    Object zwei = os.readObject();
    Object drei = os.readObject();
                          

  • DDie Objekte casten
    
    Spielfigur elb = (Spielfigur) eins;
    Spielfigur troll = (Spielfigur) zwei;
    Spielfigur zauberer = (Spielfigur) drei;
                          

  • Den Object InputStream schließen
    
    os.close();