Skip to content
IRC-Coding IRC-Coding
Netzwerkprotokolle TCP UDP IP DNS HTTP HTTPS OSI Modell TCP IP Stack

Netzwerkprotokolle: TCP, UDP, IP, DNS, HTTP/HTTPS & OSI/TCP-IP-Modelle

Netzwerkprotokolle Grundlagen mit TCP, UDP, IP, DNS, HTTP/HTTPS. OSI-Modell und TCP/IP-Stack mit praktischen Beispielen für Netzwerkkommunikation.

S

schutzgeist

2 min read
Netzwerkprotokolle: TCP, UDP, IP, DNS, HTTP/HTTPS & OSI/TCP-IP-Modelle

Netzwerkprotokolle: TCP, UDP, IP, DNS, HTTP/HTTPS & OSI/TCP-IP-Modelle

Dieser Beitrag ist eine umfassende Einführung in die Netzwerkprotokolle – inklusive TCP, UDP, IP, DNS, HTTP/HTTPS, OSI-Modell und TCP/IP-Stack mit praktischen Beispielen.

In a Nutshell

Netzwerkprotokolle regeln die Kommunikation zwischen Computern. TCP/IP ist das grundlegende Protokoll-Stack, OSI beschreibt 7 Schichten, HTTP/HTTPS ermöglichen Web-Kommunikation und DNS löst Namen in IPs auf.

Kompakte Fachbeschreibung

Netzwerkprotokolle sind standardisierte Regeln und Konventionen für die Datenkommunikation zwischen Computern in einem Netzwerk.

Wichtige Protokolle:

TCP (Transmission Control Protocol)

  • Typ: Verbindungsorientiert, zuverlässig
  • Features: 3-Wege-Handshake, Flusskontrolle, Fehlerkorrektur
  • Anwendung: Web, E-Mail, Dateitransfer
  • Port: 80 (HTTP), 443 (HTTPS), 25 (SMTP)

UDP (User Datagram Protocol)

  • Typ: Verbindungslos, unzuverlässig
  • Features: Einfach, schnell, keine Garantien
  • Anwendung: Streaming, Gaming, DNS
  • Port: 53 (DNS), 123 (NTP), 67 (DHCP)

IP (Internet Protocol)

  • Typ: Paketvermittlung, Routing
  • Versionen: IPv4 (32 Bit), IPv6 (128 Bit)
  • Features: Adressierung, Fragmentierung
  • Anwendung: Grundlage für Internet

DNS (Domain Name System)

  • Typ: Namensauflösung
  • Funktion: Domain → IP-Adresse
  • Record-Typen: A, AAAA, MX, NS, CNAME
  • Port: 53 (UDP/TCP)

HTTP/HTTPS (Hypertext Transfer Protocol)

  • Typ: Anwendungsprotokoll für Web
  • Methoden: GET, POST, PUT, DELETE
  • Status: 200 OK, 404 Not Found, 500 Server Error
  • Port: 80 (HTTP), 443 (HTTPS)

Prüfungsrelevante Stichpunkte

Diese Stichpunkte sind Prüfungsrückgrat für Fachinformatiker (IHK AP1/AP2). In der Prüfung musst du nicht nur Begriffe nennen, sondern Unterschiede erklären, Anwendungsfälle zuordnen und Zusammenhänge herstellen.

  • Netzwerkprotokolle: Regeln für computergestützte Kommunikation. Erklärung: Ohne standardisierte Protokolle könnten unterschiedliche Systeme nicht miteinander kommunizieren. Sie regeln Format, Reihenfolge, Fehlerbehandlung und Bestätigung.
  • TCP: Verbindungsorientiert, zuverlässig, 3-Wege-Handshake (SYN → SYN-ACK → ACK). Erklärung: TCP garantiert vollständige, korrekte Datenübertragung. In der Prüfung musst du den Handshake erklären und wissen, wann TCP eingesetzt wird (Web, E-Mail, FTP).
  • UDP: Verbindungslos, schnell, unzuverlässig. Erklärung: UDP sendet ohne Verbindungsaufbau und ohne Empfangsbestätigung. In der Prüfung musst du den Kontrast zu TCP herausarbeiten und Anwendungen nennen, wo Geschwindigkeit wichtiger ist (DNS, VoIP, Gaming, Streaming).
  • IP: Paketvermittlung, Routing, IPv4 (32 Bit) vs IPv6 (128 Bit). Erklärung: IP ist das Fundament des Internets. Du solltest den Unterschied zwischen IPv4 (begrenzte Adressen, NAT nötig) und IPv6 (unbegrenzte Adressen) erklären und verstehen, wie Router Pakete weiterleiten.
  • DNS: Namensauflösung, Domain → IP-Adresse. Erklärung: DNS übersetzt menschenlesbare Namen in Computer-Adressen. In der Prüfung musst du die hierarchische Struktur (Root → TLD → Authoritative) und Record-Typen (A, AAAA, MX, CNAME) erklären.
  • HTTP/HTTPS: Web-Kommunikation, Request/Response. Erklärung: Du solltest die Methoden (GET, POST, PUT, DELETE) und Statuscodes (200, 404, 500) erklären und den Unterschied zwischen HTTP (Port 80, unverschlüsselt) und HTTPS (Port 443, TLS) herausarbeiten.
  • OSI-Modell: 7-Schichten-Modell. Erklärung: In der Prüfung musst du die Schichten nennen und zuordnen: Schicht 2 = Data Link (Switch), Schicht 3 = Network (Router, IP), Schicht 4 = Transport (TCP, UDP), Schicht 7 = Application (HTTP, DNS).
  • TCP/IP-Stack: 4-Schichten-Modell. Erklärung: TCP/IP ist das praktisch genutzte Modell im Internet. Du solltest die 4 Schichten den 7 OSI-Schichten zuordnen können (z.B. TCP/IP Application = OSI 5-7).
  • IHK-relevant: Grundlage für Netzwerkadministration und -entwicklung. Erklärung: In AP1 und AP2 werden Netzwerke, Protokolle und Sicherheit regelmäßig geprüft. Wiederholtes Lernen führt zu Aha-Effekten.

Kernkomponenten

Die Kernkomponenten bilden das ** technische Fundament** der Netzwerkkommunikation. Wer diese Bausteine versteht, kann nicht nur Protokolle beschreiben, sondern auch Netzwerkprobleme analysieren und eigene Netzwerkanwendungen entwickeln.

  1. OSI-Modell: Theoretisches 7-Schichten-Modell. Warum wichtig: Das OSI-Modell bietet eine gemeinsame Sprache, um Netzwerkkommunikation zu beschreiben. Wenn ein Kollege sagt “Das Problem liegt auf Schicht 3”, weißt du sofort: Routing/IP ist betroffen. Es hilft dir, Fehler systematisch einzugrenzen.
  2. TCP/IP-Stack: Praktisches 4-Schichten-Modell. Warum wichtig: TCP/IP ist das tatsächlich im Internet eingesetzte Modell. Es ist schlanker als OSI und direkt implementierbar. Verstehst du TCP/IP, verstehst du, wie das Internet wirklich funktioniert.
  3. Transportprotokolle: TCP, UDP für Datentransport. Warum wichtig: Die Wahl des Transportprotokolls bestimmt, wie zuverlässig deine Anwendung kommuniziert. Ein Banking-App braucht TCP, ein Live-Stream braucht UDP. Diese Entscheidung fällst du als Entwickler aktiv.
  4. Netzwerkprotokolle: IP für Routing und Adressierung. Warum wichtig: IP-Adressen sind wie Postanschriften im Netzwerk. Ohne korrekte Adressierung kommen keine Daten an. IPv4 vs IPv6 ist ein aktuelles Migrationsthema in vielen Unternehmen.
  5. Anwendungsprotokolle: HTTP, DNS, SMTP für Dienste. Warum wichtig: Diese Protokolle sind die Schnittstelle zwischen Nutzer und Netzwerk. Jeder Webseitenaufruf nutzt HTTP, jeder Domain-Name braucht DNS. Als Entwickler arbeitest du täglich mit ihnen.
  6. Port-Nummern: Identifikation von Diensten. Warum wichtig: Eine IP-Adresse allein reicht nicht — auf einem Server laufen oft mehrere Dienste gleichzeitig. Ports (z.B. 80 für HTTP, 443 für HTTPS) leiten den Datenverkehr zum richtigen Programm. In der Prüfung musst du Well-Known-Ports kennen.
  7. Socket-Programmierung: Netzwerk-Kommunikation. Warum wichtig: Sockets sind die Programmierschnittstelle für Netzwerke. Wer Sockets versteht, kann eigene Server und Clients bauen — das unterscheidet einen Anwendungsentwickler von einem reinen Nutzer.
  8. Netzwerk-Sicherheit: Firewalls, VPN, TLS. Warum wichtig: Jedes offene Netzwerk ist ein Angriffsziel. TLS verschlüsselt Daten, Firewalls blockieren unerwünschten Verkehr. In der Prüfung und im Berufsalltag ist Sicherheit kein optionales Add-on, sondern Pflicht.

Praxisbeispiele

1. TCP Socket-Programmierung mit Java

Was macht dieser Code? Dieses Java-Programm zeigt einen vollständigen TCP-Server mit Thread-Pool-Verwaltung, der gleichzeitig mehrere Clients bedienen kann. Es enthält auch einen TCP-Client und Performance-Tests für Latenz und Durchsatz.

Warum ist das sinnvoll zu verstehen? TCP ist das am häufigsten genutzte Transportprotokoll im Internet. Wer versteht, wie ein TCP-Server aufgebaut ist, versteht auch, wie Webserver, Mailserver und Datenbanken grundsätzlich arbeiten. Der 3-Wege-Handshake, die Verbindungsverwaltung und die Thread-Behandlung sind zentrale Konzepte in der Prüfung und im Berufsalltag.

Was kannst du daraus lernen?

  • Wie ein ServerSocket Verbindungen annimmt und in separate Threads auslagert
  • Wie du mit BufferedReader und PrintWriter Daten bidirektional austauschst
  • Warum ein Thread-Pool wichtig ist, um nicht tausende Threads zu erstellen
  • Wie du Latenz und Durchsatz programmatisch misst
  • Wie du Client-Verbindungen sauber schließt und Ressourcen freigibst

Wenn Du Java selbs nicht kannst oder gelernt hast, dann lies Dir dieses Beispiel dennoch durch. Aber achte mehr auf die Struktur. Wann werden die globalen Variablen gesetzt, wann der eigentliche Client/Connection, wann kommen Try-Anweisungen und warum genau dort… usw. Weiter unten findest Du noch ein Python -Beispiel.

import java.io.*;
import java.net.*;
import java.util.concurrent.*;

public class TCPServerDemo {
    
    private static final int PORT = 8080;
    private static final int MAX_CLIENTS = 10;
    
    public static void main(String[] args) {
        System.out.println("=== TCP Server Demo ===");
        
        // Thread Pool für Client-Verbindungen
        ExecutorService threadPool = Executors.newFixedThreadPool(MAX_CLIENTS);
        
        try (ServerSocket serverSocket = new ServerSocket(PORT)) {
            System.out.println("TCP Server gestartet auf Port " + PORT);
            
            while (true) {
                // Auf Client-Verbindungen warten
                Socket clientSocket = serverSocket.accept();
                System.out.println("Neuer Client verbunden: " + clientSocket.getInetAddress());
                
                // Client in separatem Thread behandeln
                threadPool.execute(new ClientHandler(clientSocket));
            }
            
        } catch (IOException e) {
            System.err.println("Server-Fehler: " + e.getMessage());
        } finally {
            threadPool.shutdown();
        }
    }
    
    // Client-Handler
    static class ClientHandler implements Runnable {
        private final Socket clientSocket;
        
        public ClientHandler(Socket socket) {
            this.clientSocket = socket;
        }
        
        @Override
        public void run() {
            try (
                BufferedReader in = new BufferedReader(
                    new InputStreamReader(clientSocket.getInputStream()));
                PrintWriter out = new PrintWriter(
                    clientSocket.getOutputStream(), true)
            ) {
                
                String clientAddress = clientSocket.getInetAddress().toString();
                System.out.println("Handler für " + clientAddress + " gestartet");
                
                // Begrüßung senden
                out.println("Willkommen beim TCP Server!");
                out.println("Type 'exit' to disconnect");
                
                // Nachrichten vom Client empfangen und beantworten
                String inputLine;
                while ((inputLine = in.readLine()) != null) {
                    System.out.println("Nachricht von " + clientAddress + ": " + inputLine);
                    
                    if ("exit".equalsIgnoreCase(inputLine.trim())) {
                        out.println("Goodbye!");
                        break;
                    }
                    
                    // Echo mit Timestamp
                    String response = "Echo: " + inputLine + " [" + 
                                   java.time.LocalDateTime.now() + "]";
                    out.println(response);
                }
                
            } catch (IOException e) {
                System.err.println("Fehler bei Client-Handler: " + e.getMessage());
            } finally {
                try {
                    clientSocket.close();
                    System.out.println("Client-Verbindung geschlossen");
                } catch (IOException e) {
                    System.err.println("Fehler beim Schließen der Verbindung: " + e.getMessage());
                }
            }
        }
    }
    
    // TCP Client
    static class TCPClient {
        private final String hostname;
        private final int port;
        
        public TCPClient(String hostname, int port) {
            this.hostname = hostname;
            this.port = port;
        }
        
        public void start() {
            try (
                Socket socket = new Socket(hostname, port);
                BufferedReader in = new BufferedReader(
                    new InputStreamReader(socket.getInputStream()));
                PrintWriter out = new PrintWriter(
                    socket.getOutputStream(), true);
                BufferedReader stdIn = new BufferedReader(
                    new InputStreamReader(System.in))
            ) {
                
                System.out.println("Mit Server verbunden");
                
                // Server-Antwort empfangen
                String serverResponse = in.readLine();
                System.out.println("Server: " + serverResponse);
                
                // Interaktive Kommunikation
                String userInput;
                while ((userInput = stdIn.readLine()) != null) {
                    out.println(userInput);
                    
                    serverResponse = in.readLine();
                    System.out.println("Server: " + serverResponse);
                    
                    if ("exit".equalsIgnoreCase(userInput.trim())) {
                        break;
                    }
                }
                
            } catch (UnknownHostException e) {
                System.err.println("Unbekannter Host: " + hostname);
            } catch (IOException e) {
                System.err.println("I/O Fehler: " + e.getMessage());
            }
        }
    }
    
    // TCP Performance Test
    static class TCPPerformanceTest {
        
        public static void testTCPLatency(String hostname, int port, int iterations) {
            try (Socket socket = new Socket(hostname, port);
                 PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
                 BufferedReader in = new BufferedReader(
                     new InputStreamReader(socket.getInputStream()))) {
                
                System.out.println("=== TCP Latency Test ===");
                
                long totalTime = 0;
                
                for (int i = 0; i < iterations; i++) {
                    long startTime = System.nanoTime();
                    
                    out.println("ping");
                    String response = in.readLine();
                    
                    long endTime = System.nanoTime();
                    long latency = (endTime - startTime) / 1_000_000; // ms
                    
                    totalTime += latency;
                    
                    if (i % 10 == 0) {
                        System.out.printf("Ping %d: %dms%n", i + 1, latency);
                    }
                }
                
                double avgLatency = (double) totalTime / iterations;
                System.out.printf("Durchschnittliche Latenz: %.2fms%n", avgLatency);
                
            } catch (IOException e) {
                System.err.println("Fehler bei Latenz-Test: " + e.getMessage());
            }
        }
        
        public static void testTCPThroughput(String hostname, int port, int dataSize) {
            try (Socket socket = new Socket(hostname, port);
                 PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
                 BufferedReader in = new BufferedReader(
                     new InputStreamReader(socket.getInputStream()))) {
                
                System.out.println("=== TCP Throughput Test ===");
                
                // Testdaten erstellen
                StringBuilder testData = new StringBuilder();
                for (int i = 0; i < dataSize; i++) {
                    testData.append("A");
                }
                
                long startTime = System.nanoTime();
                
                out.println("throughput:" + testData.toString());
                String response = in.readLine();
                
                long endTime = System.nanoTime();
                long duration = (endTime - startTime) / 1_000_000; // ms
                
                double throughput = (double) dataSize / (duration / 1000.0) / 1024.0; // KB/s
                System.out.printf("Durchsatz: %.2f KB/s (%d Bytes in %dms)%n", 
                                 throughput, dataSize, duration);
                
            } catch (IOException e) {
                System.err.println("Fehler bei Throughput-Test: " + e.getMessage());
            }
        }
    }
    
    // Main für Client-Tests
    public static void main(String[] args) {
        // Server starten
        if (args.length == 0) {
            TCPServerDemo.main(args);
        } else {
            // Client-Tests
            TCPClient client = new TCPClient("localhost", PORT);
            
            // Interaktiver Client
            new Thread(() -> client.start()).start();
            
            // Performance Tests
            try {
                Thread.sleep(2000); // Warten bis Server bereit
                TCPPerformanceTest.testTCPLatency("localhost", PORT, 100);
                TCPPerformanceTest.testTCPThroughput("localhost", PORT, 10240);
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        }
    }
}

2. UDP Socket-Programmierung mit Python

Was macht dieser Code? Dieses Python-Programm zeigt einen UDP-Server mit Broadcast-Funktion, einen interaktiven UDP-Client, Performance-Tests für Latenz, Durchsatz und Packet-Loss sowie eine UDP-Multicast-Demo.

Warum ist das sinnvoll zu verstehen? UDP ist das Gegenteil von TCP: schnell, aber unzuverlässig. Wer UDP versteht, weiß, wann Geschwindigkeit wichtiger ist als Zuverlässigkeit. Broadcasting und Multicast sind fundamentale Konzepte für Netzwerk-Discovery, Streaming und IoT-Kommunikation. In der Prüfung musst du TCP und UDP kontrastieren können.

Was kannst du daraus lernen?

  • Wie du mit socket.SOCK_DGRAM UDP-Sockets erstellst
  • Warum UDP keinen Verbindungsaufbau braucht und wie recvfrom Absender-Adressen liefert
  • Wie Broadcasting an alle Clients und Multicast an eine Gruppe funktioniert
  • Warum UDP Packet-Loss hat und wie du das messen kannst
  • Wie du mit Threads gleichzeitig senden und empfangen kannst

Achte auch hier vermehrt auf den Aufbau und die Struktu des Beispiels. Schau Dir die Imports schon genauer analysieren und frage Dich warum man diese importiert und benötigen könnte.

import socket
import threading
import time
import json
from datetime import datetime

# UDP Server
class UDPServer:
    def __init__(self, host='localhost', port=9999):
        self.host = host
        self.port = port
        self.server_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        self.clients = set()
        self.running = False
        
    def start(self):
        """Start des UDP Servers"""
        self.server_socket.bind((self.host, self.port))
        self.running = True
        print(f"UDP Server läuft auf {self.host}:{self.port}")
        
        while self.running:
            try:
                # Daten empfangen
                data, client_address = self.server_socket.recvfrom(2048)
                
                # Client zur Liste hinzufügen
                self.clients.add(client_address)
                
                print(f"Nachricht von {client_address}: {data.decode()}")
                
                # Nachricht an alle Clients senden (Broadcast)
                self.broadcast(data, client_address)
                
            except Exception as e:
                print(f"Fehler beim Empfangen: {e}")
    
    def broadcast(self, message, sender_address):
        """Nachricht an alle Clients senden"""
        timestamp = datetime.now().strftime("%H:%M:%S")
        broadcast_message = f"[{timestamp}] {sender_address[0]}: {message.decode()}"
        
        for client in self.clients:
            if client != sender_address:
                try:
                    self.server_socket.sendto(broadcast_message.encode(), client)
                except Exception as e:
                    print(f"Fehler beim Senden an {client}: {e}")
    
    def stop(self):
        """Server stoppen"""
        self.running = False
        self.server_socket.close()
        print("UDP Server gestoppt")

# UDP Client
class UDPClient:
    def __init__(self, host='localhost', port=9999):
        self.host = host
        self.port = port
        self.client_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        self.running = False
        
    def start(self, username):
        """Start des UDP Clients"""
        self.running = True
        print(f"UDP Client verbunden mit {self.host}:{self.port}")
        
        # Empfangs-Thread starten
        receive_thread = threading.Thread(target=self.receive_messages)
        receive_thread.daemon = True
        receive_thread.start()
        
        try:
            while self.running:
                # Nachricht eingeben
                message = input(f"{username}: ")
                
                if message.lower() == 'exit':
                    break
                
                # Nachricht senden
                full_message = f"{username}: {message}"
                self.client_socket.sendto(full_message.encode(), (self.host, self.port))
                
        except KeyboardInterrupt:
            print("\nClient beendet")
        finally:
            self.stop()
    
    def receive_messages(self):
        """Nachrichten vom Server empfangen"""
        while self.running:
            try:
                data, server = self.client_socket.recvfrom(2048)
                print(f"\r{data.decode()}")
                print("Nachricht: ", end="", flush=True)
                
            except Exception as e:
                if self.running:
                    print(f"Fehler beim Empfangen: {e}")
                break
    
    def stop(self):
        """Client stoppen"""
        self.running = False
        self.client_socket.close()
        print("UDP Client gestoppt")

# UDP Performance Test
class UDPPerformanceTest:
    def __init__(self, host='localhost', port=9999):
        self.host = host
        self.port = port
        self.socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        
    def test_latency(self, iterations=100):
        """UDP Latenz Test"""
        print(f"=== UDP Latency Test ===")
        
        latencies = []
        
        for i in range(iterations):
            start_time = time.time()
            
            # Ping-Nachricht senden
            self.socket.sendto(b"ping", (self.host, self.port))
            
            # Antwort empfangen
            try:
                data, _ = self.socket.recvfrom(1024)
                end_time = time.time()
                
                latency = (end_time - start_time) * 1000  # ms
                latencies.append(latency)
                
                if i % 10 == 0:
                    print(f"Ping {i+1}: {latency:.2f}ms")
                    
            except socket.timeout:
                print(f"Timeout bei Ping {i+1}")
        
        if latencies:
            avg_latency = sum(latencies) / len(latencies)
            min_latency = min(latencies)
            max_latency = max(latencies)
            
            print(f"\nLatenz-Statistik:")
            print(f"  Durchschnitt: {avg_latency:.2f}ms")
            print(f"  Minimum: {min_latency:.2f}ms")
            print(f"  Maximum: {max_latency:.2f}ms")
    
    def test_throughput(self, data_size=1024, duration=5):
        """UDP Throughput Test"""
        print(f"\n=== UDP Throughput Test ===")
        
        # Testdaten erstellen
        test_data = b'A' * data_size
        
        start_time = time.time()
        packets_sent = 0
        
        while time.time() - start_time < duration:
            try:
                self.socket.sendto(test_data, (self.host, self.port))
                packets_sent += 0
                
                # Kurze Pause um Server nicht zu überlasten
                time.sleep(0.001)
                
            except Exception as e:
                print(f"Fehler beim Senden: {e}")
                break
        
        end_time = time.time()
        total_time = end_time - start_time
        
        throughput = (packets_sent * data_size) / total_time / 1024  # KB/s
        packets_per_second = packets_sent / total_time
        
        print(f"Throughput-Statistik:")
        print(f"  Pakete gesendet: {packets_sent}")
        print(f  "  Gesamtdauer: {total_time:.2f}s")
        print(f"  Pakete/Sekunde: {packets_per_second:.2f}")
        print(f"  Durchsatz: {throughput:.2f} KB/s")
    
    def test_packet_loss(self, packets=1000):
        """UDP Packet Loss Test"""
        print(f"\n=== UDP Packet Loss Test ===")
        
        packets_lost = 0
        
        for i in range(packets):
            try:
                # Sequenzielle Nummer senden
                packet = f"packet_{i}".encode()
                self.socket.sendto(packet, (self.host, self.port))
                
                # Kurze Pause
                time.sleep(0.001)
                
            except Exception as e:
                packets_lost += 1
        
        loss_rate = (packets_lost / packets) * 100
        print(f"Packet Loss Statistik:")
        print(f"  Pakete gesendet: {packets}")
        print(f"  Pakete verloren: {packets_lost}")
        print(f"  Verlustrate: {loss_rate:.2f}%")
    
    def close(self):
        """Socket schließen"""
        self.socket.close()

# UDP Multicast Demo
class UDPMulticastDemo:
    def __init__(self, multicast_group='224.0.0.1', port=5000):
        self.multicast_group = multicast_group
        self.port = port
        
    def create_multicast_sender(self):
        """Multicast Sender erstellen"""
        sender = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        
        # TTL setzen (wie viele Hops das Paket machen darf)
        ttl = struct.pack('b', 1)
        sender.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, ttl)
        
        return sender
    
    def create_multicast_receiver(self):
        """Multicast Receiver erstellen"""
        receiver = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        
        # Socket an Multicast-Adresse binden
        receiver.bind(('', self.port))
        
        # Der Multicast-Gruppe beitreten
        group = socket.inet_aton(self.multicast_group)
        receiver.setsockopt(socket.SOL_IP, socket.IP_ADD_MEMBERSHIP, group + socket.inet_aton('0.0.0.0'))
        
        return receiver
    
    def send_multicast(self, message):
        """Multicast-Nachricht senden"""
        sender = self.create_multicast_sender()
        
        try:
            sender.sendto(message.encode(), (self.multicast_group, self.port))
            print(f"Multicast gesendet: {message}")
        finally:
            sender.close()
    
    def receive_multicast(self):
        """Multicast-Nachrichten empfangen"""
        receiver = self.create_multicast_receiver()
        
        try:
            print(f"Multicast Receiver lauscht auf {self.multicast_group}:{self.port}")
            
            while True:
                try:
                    data, address = receiver.recvfrom(1024)
                    print(f"Multicast von {address}: {data.decode()}")
                    
                except KeyboardInterrupt:
                    break
                    
        finally:
            # Gruppe verlassen
            group = socket.inet_aton(self.multicast_group)
            receiver.setsockopt(socket.SOL_IP, socket.IP_DROP_MEMBERSHIP, group + socket.inet_aton('0.0.0.0'))
            receiver.close()

# Main für UDP-Demos
def main():
    import sys
    
    if len(sys.argv) > 1:
        mode = sys.argv[1]
        
        if mode == "server":
            # UDP Server starten
            server = UDPServer()
            try:
                server.start()
            except KeyboardInterrupt:
                server.stop()
                
        elif mode == "client":
            # UDP Client starten
            username = input("Ihr Name: ")
            client = UDPClient()
            client.start(username)
            
        elif mode == "performance":
            # Performance Tests
            test = UDPPerformanceTest()
            test.test_latency(100)
            test.test_throughput(1024, 5)
            test.test_packet_loss(1000)
            test.close()
            
        elif mode == "multicast_send":
            # Multicast Sender
            multicast = UDPMulticastDemo()
            while True:
                message = input("Multicast-Nachricht (oder 'exit'): ")
                if message.lower() == 'exit':
                    break
                multicast.send_multicast(message)
                
        elif mode == "multicast_receive":
            # Multicast Receiver
            multicast = UDPMulticastDemo()
            multicast.receive_multicast()
            
        else:
            print("Verwendung: python udp_demo.py [server|client|performance|multicast_send|multicast_receive]")
    else:
        print("Verwendung: python udp_demo.py [server|client|performance|multicast_send|multicast_receive]")

if __name__ == "__main__":
    main()

3. DNS-Abfragen mit verschiedenen Programmiersprachen

Was macht dieser Code? Dieses Java-Programm zeigt verschiedene DNS-Lookup-Arten: normale Namensauflösung (Domain → IP), Reverse-DNS (IP → Domain), Abfrage aller IP-Adressen, DNS-Performance-Tests und einen DNS-Caching-Vergleich (erster vs. zweiter Lookup).

Warum ist das sinnvoll zu verstehen? DNS ist das Telefonbuch des Internets. Ohne DNS müsstest du dir IP-Adressen merken. In der Prüfung und im Berufsalltag musst du DNS-Probleme diagnostizieren können — sei es ein falscher A-Record, ein abgelaufener Cache oder ein nicht erreichbarer Nameserver. Verstehst du DNS, verstehst du, warum manche Webseiten erreichbar sind und andere nicht.

Was kannst du daraus lernen?

  • Wie InetAddress.getByName() Domain-Namen in IPs übersetzt
  • Wie Reverse-DNS mit derselben Klasse funktioniert
  • Warum DNS-Caching wichtig ist und wie es die Performance beeinflusst
  • Wie du DNS-Lookups programmatisch benchmarken kannst
  • Den Unterschied zwischen IPv4 (Inet4Address) und IPv6 (Inet6Address)
import java.net.*;
import java.util.*;

public class DNSLookupDemo {
    
    // Einfache DNS-Abfrage
    public static String dnsLookup(String hostname) {
        try {
            InetAddress address = InetAddress.getByName(hostname);
            return address.getHostAddress();
        } catch (UnknownHostException e) {
            return "Unknown host: " + hostname;
        }
    }
    
    // Reverse DNS-Abfrage (IP → Hostname)
    public static String reverseDNSLookup(String ipAddress) {
        try {
            InetAddress address = InetAddress.getByName(ipAddress);
            return address.getHostName();
        } catch (UnknownHostException e) {
            return "Unknown IP: " + ipAddress;
        }
    }
    
    // Alle IP-Adressen für einen Hostnamen
    public static List<String> getAllIPAddresses(String hostname) {
        List<String> addresses = new ArrayList<>();
        
        try {
            InetAddress[] allAddresses = InetAddress.getAllByName(hostname);
            for (InetAddress addr : allAddresses) {
                addresses.add(addr.getHostAddress());
            }
        } catch (UnknownHostException e) {
            addresses.add("Unknown host: " + hostname);
        }
        
        return addresses;
    }
    
    // DNS-Record-Typen abfragen (vereinfacht)
    public static void dnsLookupWithTypes(String hostname) {
        System.out.println("=== DNS Lookup für " + hostname + " ===");
        
        // A-Record (IPv4)
        String ipv4 = dnsLookup(hostname);
        System.out.println("A-Record (IPv4): " + ipv4);
        
        // AAAA-Record (IPv6)
        try {
            InetAddress ipv6Address = InetAddress.getByName(hostname);
            if (ipv6Address instanceof Inet6Address) {
                System.out.println("AAAA-Record (IPv6): " + ipv6Address.getHostAddress());
            }
        } catch (UnknownHostException e) {
            System.out.println("AAAA-Record (IPv6): Nicht gefunden");
        }
        
        // Reverse Lookup
        if (!ipv4.equals("Unknown host: " + hostname)) {
            String reverse = reverseDNSLookup(ipv4);
            System.out.println("PTR-Record (Reverse): " + reverse);
        }
        
        // MX-Records (Mail Exchange)
        dnsLookupMX(hostname);
        
        // NS-Records (Name Server)
        dnsLookupNS(hostname);
    }
    
    // MX-Records abfragen
    public static void dnsLookupMX(String hostname) {
        try {
            // In der Praxis würde man DNS-Bibliotheken wie dnsjava verwenden
            // Hier zeigen wir das Konzept
            System.out.println("MX-Records: Verwendet DNS-Bibliotheken für vollständige Abfrage");
            
            // Beispiel mit einfacher Logik
            if (hostname.endsWith(".com")) {
                System.out.println("  MX: mail." + hostname + " (Beispiel)");
            }
            
        } catch (Exception e) {
            System.out.println("MX-Records: Fehler bei Abfrage - " + e.getMessage());
        }
    }
    
    // NS-Records abfragen
    public static void dnsLookupNS(String hostname) {
        try {
            System.out.println("NS-Records: Verwendet DNS-Bibliotheken für vollständige Abfrage");
            
            // Beispiel mit einfacher Logik
            String[] commonNS = {"ns1." + hostname, "ns2." + hostname};
            for (String ns : commonNS) {
                System.out.println("  NS: " + ns + " (Beispiel)");
            }
            
        } catch (Exception e) {
            System.out.println("NS-Records: Fehler bei Abfrage - " + e.getMessage());
        }
    }
    
    // DNS-Performance-Test
    public static void dnsPerformanceTest(String hostname, int iterations) {
        System.out.println("=== DNS Performance Test ===");
        
        long totalTime = 0;
        int successfulLookups = 0;
        
        for (int i = 0; i < iterations; i++) {
            long startTime = System.nanoTime();
            
            String result = dnsLookup(hostname);
            
            long endTime = System.nanoTime();
            long duration = (endTime - startTime) / 1_000_000; // ms
            
            if (!result.startsWith("Unknown host")) {
                totalTime += duration;
                successfulLookups++;
            }
            
            if (i % 10 == 0) {
                System.out.printf("Lookup %d: %dms%n", i + 1, duration);
            }
        }
        
        if (successfulLookups > 0) {
            double avgTime = (double) totalTime / successfulLookups;
            System.out.printf("Durchschnittliche DNS-Lookup Zeit: %.2fms%n", avgTime);
            System.out.printf("Erfolgreiche Lookups: %d/%d%n", successfulLookups, iterations);
        }
    }
    
    // DNS-Caching Demo
    public static void dnsCachingDemo(String hostname) {
        System.out.println("=== DNS Caching Demo ===");
        
        // Erster Lookup (Cache-Miss)
        long start = System.nanoTime();
        String result1 = dnsLookup(hostname);
        long firstLookup = (System.nanoTime() - start) / 1_000_000;
        
        // Zweiter Lookup (Cache-Hit)
        start = System.nanoTime();
        String result2 = dnsLookup(hostname);
        long secondLookup = (System.nanoTime() - start) / 1_000_000;
        
        System.out.println("Erster Lookup: " + firstLookup + "ms");
        System.out.println("Zweiter Lookup: " + secondLookup + "ms");
        
        if (secondLookup < firstLookup) {
            System.out.println("DNS-Caching aktiv (zweiter Lookup schneller)");
        } else {
            System.out.println("Kein DNS-Caching erkannt");
        }
        
        // Ergebnisse vergleichen
        System.out.println("Ergebnis 1: " + result1);
        System.out.println("Ergebnis 2: " + result2);
        System.out.println("Ergebnisse gleich: " + result1.equals(result2));
    }
    
    // IPv6 Support Test
    public static void ipv6SupportTest(String hostname) {
        System.out.println("=== IPv6 Support Test ===");
        
        try {
            // IPv6-Adresse auflösen
            InetAddress[] addresses = InetAddress.getAllByName(hostname);
            
            boolean hasIPv4 = false;
            boolean hasIPv6 = false;
            
            for (InetAddress addr : addresses) {
                if (addr instanceof Inet4Address) {
                    hasIPv4 = true;
                    System.out.println("IPv4: " + addr.getHostAddress());
                } else if (addr instanceof Inet6Address) {
                    hasIPv6 = true;
                    System.out.println("IPv6: " + addr.getHostAddress());
                }
            }
            
            System.out.println("IPv4 Support: " + (hasIPv4 ? "Ja" : "Nein"));
            System.out.println("IPv6 Support: " + (hasIPv6 ? "Ja" : "Nein"));
            
        } catch (UnknownHostException e) {
            System.out.println("IPv6 Support Test fehlgeschlagen: " + e.getMessage());
        }
    }
    
    public static void main(String[] args) {
        String hostname = "google.com";
        
        if (args.length > 0) {
            hostname = args[0];
        }
        
        // Verschiedene DNS-Abfragen
        dnsLookupWithTypes(hostname);
        
        // Performance-Test
        dnsPerformanceTest(hostname, 50);
        
        // Caching-Demo
        dnsCachingDemo(hostname);
        
        // IPv6 Support Test
        ipv6SupportTest(hostname);
    }
}

4. HTTP/HTTPS Client mit verschiedenen Features

Was macht dieser Code? Dieses Python-Programm zeigt einen vollständigen HTTP/HTTPS-Client mit erweiterten Features: Retry-Strategie, verschiedene HTTP-Methoden (GET, POST, HEAD, OPTIONS), SSL/TLS-Zertifikatsprüfung, Cookie-Handling, Redirect-Tracking, Datei-Download mit Fortschrittsanzeige, Performance-Tests und einen API-Client für REST-Endpoints.

Warum ist das sinnvoll zu verstehen? HTTP/HTTPS ist das wichtigste Anwendungsprotokoll im Web. Jeder API-Aufruf, jeder Webseitenbesuch und jeder Datenabgleich nutzt HTTP. Wer versteht, wie Requests, Responses, Statuscodes, Header und Sessions funktionieren, kann APIs debuggen, Sicherheitsprobleme erkennen und performante Webanwendungen bauen. In der Prüfung sind HTTP-Methoden und Statuscodes Standardfragen.

Was kannst du daraus lernen?

  • Wie du mit requests.Session() eine wiederverwendbare Verbindung aufbaust
  • Warum Retry-Strategien wichtig sind und wie du sie mit urllib3.util.retry implementierst
  • Wie du SSL-Zertifikatsinformationen und TLS-Versionen ausliest
  • Wie Cookies automatisch zwischen Requests weitergegeben werden
  • Wie du Redirects verfolgst oder blockierst
  • Wie du große Dateien mit stream=True effizient herunterlädst
  • Wie du einen generischen REST-API-Client mit CRUD-Operationen baust
import requests
import json
import time
import ssl
import urllib3
from urllib3.util.retry import Retry
from datetime import datetime

# HTTP Client mit erweiterten Features
class HTTPClient:
    def __init__(self):
        self.session = requests.Session()
        self.setup_session()
        
    def setup_session(self):
        """Session konfigurieren"""
        # Retry-Strategie
        retry_strategy = Retry(
            total=3,
            backoff_factor=1,
            status_forcelist=[429, 500, 502, 503, 504],
            allowed_methods=["HEAD", "GET", "OPTIONS"]
        )
        
        adapter = urllib3.HTTPAdapter(max_retries=retry_strategy)
        self.session.mount("https://", adapter)
        self.session.mount("http://", adapter)
        
        # Headers
        self.session.headers.update({
            'User-Agent': 'HTTPClient-Demo/1.0',
            'Accept': 'application/json',
            'Accept-Language': 'de-DE,de;q=0.9,en;q=0.8',
            'Cache-Control': 'no-cache'
        })
        
        # Timeout
        self.session.timeout = 30
        
        print("HTTP Client konfiguriert")
    
    def get_request(self, url, params=None):
        """GET-Request mit Fehlerbehandlung"""
        try:
            print(f"GET Request: {url}")
            
            start_time = time.time()
            response = self.session.get(url, params=params)
            end_time = time.time()
            
            self.print_response_info(response, end_time - start_time)
            return response
            
        except requests.exceptions.RequestException as e:
            print(f"GET Request fehlgeschlagen: {e}")
            return None
    
    def post_request(self, url, data=None, json_data=None):
        """POST-Request mit Daten"""
        try:
            print(f"POST Request: {url}")
            
            if json_data:
                print(f"JSON-Daten: {json.dumps(json_data, indent=2)}")
            
            start_time = time.time()
            
            if json_data:
                response = self.session.post(url, json=json_data)
            else:
                response = self.session.post(url, data=data)
            
            end_time = time.time()
            
            self.print_response_info(response, end_time - start_time)
            return response
            
        except requests.exceptions.RequestException as e:
            print(f"POST Request fehlgeschlagen: {e}")
            return None
    
    def print_response_info(self, response, duration):
        """Response-Informationen ausgeben"""
        print(f"Status Code: {response.status_code}")
        print(f"Response Time: {duration:.2f}s")
        print(f"Content-Type: {response.headers.get('Content-Type', 'N/A')}")
        print(f"Content-Length: {response.headers.get('Content-Length', 'N/A')}")
        
        # Headers ausgeben
        if response.headers:
            print("Response Headers:")
            for key, value in response.headers.items():
                print(f"  {key}: {value}")
    
    def test_http_methods(self, url):
        """Verschiedene HTTP-Methoden testen"""
        print(f"=== HTTP Methods Test für {url} ===")
        
        # GET
        print("\n--- GET ---")
        response = self.get_request(url)
        
        # HEAD
        print("\n--- HEAD ---")
        try:
            response = self.session.head(url)
            print(f"HEAD Status: {response.status_code}")
            print(f"HEAD Headers: {dict(response.headers)}")
        except Exception as e:
            print(f"HEAD Request fehlgeschlagen: {e}")
        
        # OPTIONS
        print("\n--- OPTIONS ---")
        try:
            response = self.session.options(url)
            print(f"OPTIONS Status: {response.status_code}")
            allowed_methods = response.headers.get('Allow', 'N/A')
            print(f"Erlaubte Methoden: {allowed_methods}")
        except Exception as e:
            print(f"OPTIONS Request fehlgeschlagen: {e}")
    
    def test_https_features(self, url):
        """HTTPS-Features testen"""
        print(f"=== HTTPS Features Test für {url} ===")
        
        try:
            # SSL-Zertifikat-Informationen
            response = self.session.get(url)
            
            # SSL-Informationen ausgeben
            cert_info = response.raw._connection.peer.cert
            if cert_info:
                print("SSL-Zertifikat-Informationen:")
                for cert in cert_info:
                    print(f"  Subject: {cert.subject}")
                    print(f"  Issuer: {cert.issuer}")
                    print(f"  Valid from: {cert.not_valid_before}")
                    print(f"  Valid until: {cert.not_valid_after}")
                    print(f"  Serial: {cert.serial_number}")
            
            # TLS-Version
            tls_version = response.raw._connection.tls_version
            print(f"TLS-Version: {tls_version}")
            
            # Cipher Suite
            cipher_suite = response.raw._connection.cipher
            print(f"Cipher Suite: {cipher_suite}")
            
        except Exception as e:
            print(f"HTTPS Features Test fehlgeschlagen: {e}")
    
    def test_authentication(self, url, username, password):
        """HTTP-Authentifizierung testen"""
        print(f"=== Authentication Test für {url} ===")
        
        # Basic Authentication
        try:
            from requests.auth import HTTPBasicAuth
            
            auth = HTTPBasicAuth(username, password)
            response = self.session.get(url, auth=auth)
            
            print(f"Basic Auth Status: {response.status_code}")
            
            if response.status_code == 200:
                print("Basic Authentication erfolgreich")
            else:
                print("Basic Authentication fehlgeschlagen")
                
        except Exception as e:
            print(f"Authentication Test fehlgeschlagen: {e}")
    
    def test_cookies(self, url):
        """Cookie-Handling testen"""
        print(f"=== Cookie Test für {url} ===")
        
        try:
            # Erste Request ohne Cookies
            response1 = self.session.get(url)
            print(f"Erster Request Status: {response1.status_code}")
            print(f"Cookies nach erstem Request: {len(self.session.cookies)}")
            
            # Zweiter Request mit Cookies
            response2 = self.session.get(url)
            print(f"Zweiter Request Status: {response2.status_code}")
            print(f"Cookies nach zweitem Request: {len(self.session.cookies)}")
            
            # Cookie-Informationen
            if self.session.cookies:
                print("Cookie-Details:")
                for cookie in self.session.cookies:
                    print(f"  {cookie.name}: {cookie.value}")
                    print(f"    Domain: {cookie.domain}")
                    print(f"    Path: {cookie.path}")
                    print(f"    Secure: {cookie.secure}")
                    print(f"    HttpOnly: {cookie.has_attr('HttpOnly')}")
            
        except Exception as e:
            print(f"Cookie Test fehlgeschlagen: {e}")
    
    def test_redirects(self, url):
        """Redirect-Handling testen"""
        print(f"=== Redirect Test für {url} ===")
        
        try:
            # Redirects nicht folgen
            response = self.session.get(url, allow_redirects=False)
            print(f"Status ohne Redirects: {response.status_code}")
            
            if 300 <= response.status_code < 400:
                location = response.headers.get('Location', 'N/A')
                print(f"Redirect zu: {location}")
            
            # Redirects folgen
            response = self.session.get(url, allow_redirects=True)
            print(f"Status mit Redirects: {response.status_code}")
            print(f"Final URL: {response.url}")
            
            # Redirect-Verlauf
            if hasattr(response.history, '__iter__'):
                print("Redirect-Verlauf:")
                for i, resp in enumerate(response.history):
                    print(f"  {i+1}. {resp.status_code} -> {resp.url}")
            
        except Exception as e:
            print(f"Redirect Test fehlgeschlagen: {e}")
    
    def test_download(self, url, save_path=None):
        """Datei-Download testen"""
        print(f"=== Download Test für {url} ===")
        
        try:
            response = self.session.get(url, stream=True)
            
            content_length = int(response.headers.get('content-length', 0))
            print(f"Dateigröße: {content_length} bytes")
            
            if save_path:
                with open(save_path, 'wb') as f:
                    downloaded = 0
                    chunk_size = 8192
                    
                    for chunk in response.iter_content(chunk_size=chunk_size):
                        f.write(chunk)
                        downloaded += chunk_size
                        
                        # Progress anzeigen
                        progress = (downloaded / content_length) * 100 if content_length > 0 else 0
                        print(f"\rDownload: {progress:.1f}%", end="", flush=True)
                
                print(f"\nDatei gespeichert: {save_path}")
            
        except Exception as e:
            print(f"Download fehlgeschlagen: {e}")
    
    def performance_test(self, url, iterations=10):
        """Performance-Test"""
        print(f"=== Performance Test für {url} ===")
        
        times = []
        
        for i in range(iterations):
            try:
                start_time = time.time()
                response = self.session.get(url)
                end_time = time.time()
                
                duration = end_time - start_time
                times.append(duration)
                
                if i % 5 == 0:
                    print(f"Request {i+1}: {duration:.3f}s")
                
            except Exception as e:
                print(f"Request {i+1} fehlgeschlagen: {e}")
        
        if times:
            avg_time = sum(times) / len(times)
            min_time = min(times)
            max_time = max(times)
            
            print(f"\nPerformance-Statistik:")
            print(f"  Requests: {len(times)}")
            print(f"  Durchschnitt: {avg_time:.3f}s")
            print(f"  Minimum: {min_time:.3f}s")
            print(f"  Maximum: {max_time:.3f}s")
            print(f"  Requests/Sekunde: {1/avg_time:.2f}")

# API-Client für REST-APIs
class APIClient(HTTPClient):
    def __init__(self, base_url):
        super().__init__()
        self.base_url = base_url.rstrip('/')
        
        # API-spezifische Headers
        self.session.headers.update({
            'Content-Type': 'application/json',
            'Accept': 'application/json'
        })
    
    def get_resource(self, resource, params=None):
        """GET Resource"""
        url = f"{self.base_url}/{resource.lstrip('/')}"
        return self.get_request(url, params)
    
    def create_resource(self, resource, data):
        """POST Resource"""
        url = f"{self.base_url}/{resource.lstrip('/')}"
        return self.post_request(url, json_data=data)
    
    def update_resource(self, resource, data):
        """PUT Resource"""
        url = f"{self.base_url}/{resource.lstrip('/')}"
        try:
            response = self.session.put(url, json=data)
            self.print_response_info(response, 0)
            return response
        except Exception as e:
            print(f"PUT Request fehlgeschlagen: {e}")
            return None
    
    def delete_resource(self, resource):
        """DELETE Resource"""
        url = f"{self.base_url}/{resource.lstrip('/')}"
        try:
            response = self.session.delete(url)
            self.print_response_info(response, 0)
            return response
        except Exception as e:
            print(f"DELETE Request fehlgeschlagen: {e}")
            return None

# Main für HTTP-Demos
def main():
    import sys
    
    # HTTP Client Demo
    client = HTTPClient()
    
    # HTTP-Methoden Test
    client.test_http_methods("https://httpbin.org")
    
    # HTTPS Features Test
    client.test_https_features("https://google.com")
    
    # Redirect Test
    client.test_redirects("http://httpbin.org/redirect/1")
    
    # Cookie Test
    client.test_cookies("https://httpbin.org/cookies/set/test/value")
    
    # Performance Test
    client.performance_test("https://httpbin.org/get", 20)
    
    # API Client Demo
    api_client = APIClient("https://jsonplaceholder.typicode.com")
    
    # GET Users
    users_response = api_client.get_resource("/users")
    if users_response:
        print(f"Users: {users_response.json()}")
    
    # Create Post
    new_post = {
        "title": "Test Post",
        "body": "Test Body",
        "userId": 1
    }
    create_response = api_client.create_resource("/posts", new_post)
    
    # Download Test
    client.test_download("https://httpbin.org/bytes/1024", "test_download.bin")

if __name__ == "__main__":
    main()

OSI-Modell vs TCP/IP-Stack

OSI-Modell (7 Schichten)

SchichtNameFunktionBeispiele
7ApplicationAnwendungsprotokolleHTTP, FTP, SMTP
6PresentationDatenumwandlungSSL/TLS, JPEG
5SessionSitzungsverwaltungNetBIOS, RPC
4TransportEnd-to-End-KommunikationTCP, UDP
3NetworkRouting und AdressierungIP, ICMP
2Data LinkFrame-ÜbertragungEthernet, WiFi
1PhysicalBit-ÜbertragungKabel, Funk

TCP/IP-Stack (4 Schichten)

SchichtNameOSI-EntsprechungProtokolle
4Application5-7HTTP, FTP, DNS
3Transport4TCP, UDP
2Internet3IP, ICMP
1Network Access1-2Ethernet, WiFi

Wichtige Port-Nummern

Well-Known Ports (0-1023)

PortProtokollDienst
20FTPFile Transfer (Data)
21FTPFile Transfer (Control)
22SSHSecure Shell
23TelnetRemote Terminal
25SMTPE-Mail
53DNSDomain Name System
80HTTPWeb (unverschlüsselt)
110POP3E-Mail (Post Office)
143IMAPE-Mail (Internet Message)
443HTTPSWeb (verschlüsselt)
993IMAPSIMAP over SSL
995POP3SPOP3 over SSL

Registered Ports (1024-49151)

PortProtokollDienst
3306MySQLDatenbank
5432PostgreSQLDatenbank
8080HTTP-AltWeb (alternativ)
8443HTTPS-AltWeb (alternativ)
27017MongoDBNoSQL-Datenbank

TCP vs UDP Vergleich

EigenschaftTCPUDP
VerbindungVerbindungsorientiertVerbindungslos
ZuverlässigkeitGarantiertNicht garantiert
ReihenfolgeGarantiertNicht garantiert
FlusskontrolleJaNein
FehlerkorrekturJaNein
OverheadHochNiedrig
GeschwindigkeitLangsamerSchneller
AnwendungWeb, E-MailStreaming, Gaming

HTTP-Statuscodes Übersicht

1xx Informational

  • 100 Continue: Fortsetzung
  • 101 Switching Protocols: Protokoll-Wechsel

2xx Success

  • 200 OK: Erfolgreich
  • 201 Created: Erstellt
  • 204 No Content: Kein Inhalt

3xx Redirection

  • 301 Moved Permanently: Permanent verschoben
  • 302 Found: Temporär verschoben
  • 304 Not Modified: Nicht verändert

4xx Client Error

  • 400 Bad Request: Ungültige Anfrage
  • 401 Unauthorized: Nicht autorisiert
  • 403 Forbidden: Verboten
  • 404 Not Found: Nicht gefunden
  • 429 Too Many Requests: Zu viele Anfragen

5xx Server Error

  • 500 Internal Server Error: Interner Serverfehler
  • 502 Bad Gateway: Gateway-Fehler
  • 503 Service Unavailable: Dienst nicht verfügbar

DNS-Record-Typen

TypBeschreibungBeispiel
AIPv4-Adresseexample.com → 93.184.216.34
AAAAIPv6-Adresseexample.com → 2606:2800:220:1
MXMail Exchangeexample.com → mail.example.com
NSName Serverexample.com → ns1.example.com
CNAMECanonical Namewww.example.com → example.com
TXTText-Informationexample.com → “v=spf1 include:_spf.google.com ~all”
PTRPointer (Reverse)93.184.216.34 → example.com

Socket-Programmierung Grundlagen

TCP Socket Lifecycle

// Server
1. ServerSocket erstellen
2. Auf Verbindung warten (accept)
3. InputStream/OutputStream erstellen
4. Daten austauschen
5. Verbindung schließen

// Client
1. Socket erstellen
2. Mit Server verbinden
3. InputStream/OutputStream erstellen
4. Daten austauschen
5. Verbindung schließen

UDP Socket Lifecycle

// Server
1. DatagramSocket erstellen
2. Auf Pakete warten (receive)
3. Paket verarbeiten
4. Antwort senden (send)

// Client
1. DatagramSocket erstellen
2. Paket senden (send)
3. Auf Antwort warten (receive)
4. Socket schließen

Vorteile und Nachteile

Vorteile von Netzwerkprotokollen

  • Standardisierung: Interoperabilität zwischen Systemen
  • Skalierbarkeit: Unterstützung für große Netzwerke
  • Zuverlässigkeit: Fehlerbehandlung und Wiederherstellung
  • Flexibilität: Verschiedene Protokolle für verschiedene Zwecke

Nachteile

  • Komplexität: Viele Schichten und Protokolle
  • Overhead: Zusätzliche Daten für Protokoll-Informationen
  • Sicherheit: Angriffsflächen für Hacker
  • Performance: Netzwerk-Latenzen

Häufige Prüfungsfragen

  1. Was ist der Unterschied zwischen TCP und UDP? TCP ist verbindungsorientiert und zuverlässig, UDP ist verbindungslos und schnell aber unzuverlässig.

  2. Erklären Sie das OSI-Modell! Das OSI-Modell beschreibt 7 Schichten für Netzwerkkommunikation von Physical bis Application.

  3. Was ist DNS und wie funktioniert es? DNS übersetzt Domain-Namen in IP-Adressen und umgekehrt über hierarchische Namenserver.

  4. Wann verwendet man HTTP vs HTTPS? HTTP für unverschlüsselte Kommunikation, HTTPS für verschlüsselte Kommunikation mit SSL/TLS.

Wichtigste Quellen

  1. https://www.ietf.org/rfc/rfc791.html (TCP)
  2. https://www.ietf.org/rfc/rfc768.html (UDP)
  3. https://www.ietf.org/rfc/rfc1035.html (DNS)
  4. https://www.ietf.org/rfc/rfc2616.html (HTTP/1.1)
Zurück zum Blog
Share: