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.
- 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.
- 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.
- 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.
- 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.
- 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.
- 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.
- 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.
- 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_DGRAMUDP-Sockets erstellst - Warum UDP keinen Verbindungsaufbau braucht und wie
recvfromAbsender-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.retryimplementierst - 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=Trueeffizient 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)
| Schicht | Name | Funktion | Beispiele |
|---|---|---|---|
| 7 | Application | Anwendungsprotokolle | HTTP, FTP, SMTP |
| 6 | Presentation | Datenumwandlung | SSL/TLS, JPEG |
| 5 | Session | Sitzungsverwaltung | NetBIOS, RPC |
| 4 | Transport | End-to-End-Kommunikation | TCP, UDP |
| 3 | Network | Routing und Adressierung | IP, ICMP |
| 2 | Data Link | Frame-Übertragung | Ethernet, WiFi |
| 1 | Physical | Bit-Übertragung | Kabel, Funk |
TCP/IP-Stack (4 Schichten)
| Schicht | Name | OSI-Entsprechung | Protokolle |
|---|---|---|---|
| 4 | Application | 5-7 | HTTP, FTP, DNS |
| 3 | Transport | 4 | TCP, UDP |
| 2 | Internet | 3 | IP, ICMP |
| 1 | Network Access | 1-2 | Ethernet, WiFi |
Wichtige Port-Nummern
Well-Known Ports (0-1023)
| Port | Protokoll | Dienst |
|---|---|---|
| 20 | FTP | File Transfer (Data) |
| 21 | FTP | File Transfer (Control) |
| 22 | SSH | Secure Shell |
| 23 | Telnet | Remote Terminal |
| 25 | SMTP | |
| 53 | DNS | Domain Name System |
| 80 | HTTP | Web (unverschlüsselt) |
| 110 | POP3 | E-Mail (Post Office) |
| 143 | IMAP | E-Mail (Internet Message) |
| 443 | HTTPS | Web (verschlüsselt) |
| 993 | IMAPS | IMAP over SSL |
| 995 | POP3S | POP3 over SSL |
Registered Ports (1024-49151)
| Port | Protokoll | Dienst |
|---|---|---|
| 3306 | MySQL | Datenbank |
| 5432 | PostgreSQL | Datenbank |
| 8080 | HTTP-Alt | Web (alternativ) |
| 8443 | HTTPS-Alt | Web (alternativ) |
| 27017 | MongoDB | NoSQL-Datenbank |
TCP vs UDP Vergleich
| Eigenschaft | TCP | UDP |
|---|---|---|
| Verbindung | Verbindungsorientiert | Verbindungslos |
| Zuverlässigkeit | Garantiert | Nicht garantiert |
| Reihenfolge | Garantiert | Nicht garantiert |
| Flusskontrolle | Ja | Nein |
| Fehlerkorrektur | Ja | Nein |
| Overhead | Hoch | Niedrig |
| Geschwindigkeit | Langsamer | Schneller |
| Anwendung | Web, E-Mail | Streaming, 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
| Typ | Beschreibung | Beispiel |
|---|---|---|
| A | IPv4-Adresse | example.com → 93.184.216.34 |
| AAAA | IPv6-Adresse | example.com → 2606:2800:220:1 |
| MX | Mail Exchange | example.com → mail.example.com |
| NS | Name Server | example.com → ns1.example.com |
| CNAME | Canonical Name | www.example.com → example.com |
| TXT | Text-Information | example.com → “v=spf1 include:_spf.google.com ~all” |
| PTR | Pointer (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
-
Was ist der Unterschied zwischen TCP und UDP? TCP ist verbindungsorientiert und zuverlässig, UDP ist verbindungslos und schnell aber unzuverlässig.
-
Erklären Sie das OSI-Modell! Das OSI-Modell beschreibt 7 Schichten für Netzwerkkommunikation von Physical bis Application.
-
Was ist DNS und wie funktioniert es? DNS übersetzt Domain-Namen in IP-Adressen und umgekehrt über hierarchische Namenserver.
-
Wann verwendet man HTTP vs HTTPS? HTTP für unverschlüsselte Kommunikation, HTTPS für verschlüsselte Kommunikation mit SSL/TLS.
Wichtigste Quellen
- https://www.ietf.org/rfc/rfc791.html (TCP)
- https://www.ietf.org/rfc/rfc768.html (UDP)
- https://www.ietf.org/rfc/rfc1035.html (DNS)
- https://www.ietf.org/rfc/rfc2616.html (HTTP/1.1)