Zum Inhalt
Bytearium

Keine Werbung und keine Partnerlinks aktiv

Netzwerke

TCP

Das Transmission Control Protocol stellt Anwendungen einen zuverlässigen, geordneten Bytestrom zwischen Endpunkten bereit.

TCP ist die höfliche Post des Internets: Es will für jedes Paket eine Quittung und schickt nach, was verloren ging. Viele Dienste verlassen sich noch auf diese Pingeligkeit, und meistens ist das gut so.

Kurz gesagt

TCP (Transmission Control Protocol) liefert einen zuverlässigen, geordneten Bytestrom zwischen zwei Programmen auf verschiedenen Rechnern. Es läuft auf IP, das nur einzelne Pakete befördert, und ergänzt Nummerierung, Empfangsbestätigungen und Flusssteuerung. TCP selbst verschlüsselt nicht; Verschlüsselung ist eine eigene Schicht wie TLS.

So funktioniert’s

  1. Ein Bytestrom zwischen zwei Programmen. RFC 9293, die aktuelle TCP-Spezifikation, beschreibt TCP als zuverlässigen Bytestrom in fester Reihenfolge zwischen Prozessen auf Hosts. Ports (Zahlen im Header) sagen dem empfangenden Rechner, für welches Programm ein Segment bestimmt ist. Die Prüfsumme ist Pflicht, nie optional.
  2. Eine Verbindung wird durch vier Werte benannt. Die Spezifikation hält im Kontrollblock einer Verbindung die lokale und die entfernte IP-Adresse sowie den lokalen und den entfernten Port fest. Kurz: Eine Verbindung ist durch diese zwei Adressen mit ihren Ports bestimmt (eigene Zusammenfassung).
  3. Sequenznummern zählen Bytes. Jedes Byte des Stroms trägt eine Sequenznummer, gerechnet modulo 2^32. Die Bestätigung ist kumulativ: Sie sagt „alles bis zu diesem Byte ist angekommen“. Jede Seite beginnt bei einer initialen Sequenznummer (ISN), die beim Verbindungsaufbau im Drei-Wege-Handshake (SYN, SYN-ACK, ACK) ausgetauscht wird.
  4. Zuverlässig heißt: nochmal senden. Was nicht bestätigt wird, wird erneut gesendet (eigene Zusammenfassung des Mechanismus). Im Header steht außerdem ein Fenster: Der Empfänger teilt dem Sender mit, wie viele Daten er gerade annehmen will, damit ein langsamer Empfänger nicht überflutet wird.
  5. Überlastkontrolle ist Pflicht. RFC 9293 führt die Überlastkontrolle als Anforderung. RFC 5681 beschreibt die zwei Grenzen des Senders: das Überlastfenster (cwnd), das der Sender nach dem anpasst, was er über das Netz lernt, und das Fenster des Empfängers (rwnd). Der Sender darf höchstens das Kleinere von beiden senden. Slow Start vergrößert cwnd anfangs schnell, die Überlastvermeidung danach vorsichtiger.
  6. Eine Verbindung durchläuft Zustände. Die Spezifikation definiert die Zustände, die eine Verbindung durchläuft, von LISTEN und SYN-SENT über ESTABLISHED bis zu den Zuständen beim Schließen. Nach dem Schließen wartet die Seite, die zuletzt geschlossen hat, im Zustand TIME-WAIT die doppelte maximale Segmentlebensdauer (MSL), damit späte Segmente der alten Verbindung nicht in einer neuen landen. Die Spezifikation setzt die MSL auf 2 Minuten und nennt das eine Ingenieursentscheidung. Viele kurze Verbindungen hintereinander können deshalb viele Sockets in TIME-WAIT hinterlassen, was normal ist (der letzte Satz ist unsere eigene Folgerung).
  7. Segmentgröße. Sendet die Gegenstelle keine MSS-Option (Maximum Segment Size), gilt als Vorgabe 536 Byte für IPv4 und 1.220 Byte für IPv6.
  8. Keine Verschlüsselung. RFC 5925 beschreibt die TCP Authentication Option, die Segmente authentifiziert, und hält klar fest, dass sie keine Verschlüsselung bietet und kein Ersatz für TLS ist. TLS 1.3 (RFC 8446) soll Mithören, Manipulation und Fälschung von Nachrichten auf einer Verbindung verhindern. Dass TCP die Daten befördert, ohne sie zu verschlüsseln, ist unsere Lesart dieser beiden Dokumente.

In der Praxis

Das Werkzeug ss zeigt die Sockets eines Linux-Rechners:

ss -tln          # TCP, lauschend, numerisch: welche Ports bedient dieser Rechner?
ss -tan          # alle TCP-Verbindungen mit Zustand (ESTAB, TIME-WAIT, …)
ss -ti           # je Verbindung: interne TCP-Informationen
ss -to           # je Verbindung: Timer, auch Zähler für erneutes Senden

Ein Beispiel aus dem Bytearium-Inventar: Die Portainer-Weboberfläche auf der Docker-VM ist per HTTPS auf Port 9443 erreichbar (Lesung vom 14. Okt. 2026). Auf dieser Maschine zeigt ss -tln schnell, ob etwas auf 9443 lauscht und auf welchen Adressen; für diesen Artikel haben wir es nicht ausgeführt, deshalb steht keine Ausgabe da.

Öffnen und Schließen, Schritt für Schritt

Eine TCP-Verbindung beginnt mit dem Drei-Wege-Handshake: Der Client schickt ein Segment mit gesetztem SYN-Flag und seiner Anfangssequenznummer, der Server antwortet mit SYN und ACK, der Client bestätigt mit ACK. Erst dann ist die Verbindung ESTABLISHED, und deshalb kostet TCP immer eine Umlaufzeit, bevor das erste Datenbyte fließt. Das Schließen ist ein vierstufiger Austausch von FIN und ACK in beide Richtungen, und die Seite, die zuletzt schließt, hält die Verbindung eine Weile in TIME-WAIT. Ein Server mit Tausenden kurzer Verbindungen zeigt in ss -tan deshalb Tausende TIME-WAIT-Einträge; das ist Buchhaltung, kein Leck.

Wann TCP das falsche Werkzeug ist

UDP, definiert in RFC 768, verschickt Datagramme mit einem Minimum an Mechanik: keine Verbindung, keine Reihenfolge, keine Neuübertragung, und der RFC selbst sagt, dass Anwendungen mit Bedarf an geordneter, zuverlässiger Zustellung TCP nehmen sollen. Die Kehrseite: UDP wartet nie. DNS-Abfragen, Sprach- und Videoanrufe, Spielverkehr und viele Streaming-Protokolle nutzen es, weil ein verspätetes Paket weniger wert ist als ein verlorenes. Noch neuer ist QUIC (RFC 9000), ein Transport, der auf UDP läuft, TLS 1.3 eingebaut hat und schnellen Verbindungsaufbau sowie mehrere Ströme bietet, ohne dass ein verlorenes Paket die anderen aufhält; HTTP/3 nutzt es. Wenn du eine Firewall für einen modernen Webdienst öffnest, denk daran, dass „Port 443“ heute UDP genauso meinen kann wie TCP.

Verbindungen, die einschlafen

Heimrouter und Firewalls machen NAT und führen eine Tabelle der Verbindungen. Eine TCP-Verbindung ohne Verkehr kann nach Minuten aus dieser Tabelle fliegen, und das nächste Segment trifft dann auf einen Router, der die Verbindung nicht mehr kennt. SSH-Sitzungen, die nach der Kaffeepause „hängen“, und Datenbankverbindungen, die morgens beim ersten Zugriff scheitern, sind meist genau das. Keepalive-Einstellungen am Client (ServerAliveInterval bei SSH, TCP-Keepalive am Socket) schicken regelmäßig kleine Segmente, damit der Eintrag frisch bleibt; alternativ verbindest du bei Fehler neu und behandelst den Abbruch als Normalfall.

Prüfliste

  • Prüfe mit ss -tln, welche Ports ein Rechner wirklich bedient, und schließe, was du nicht brauchst.
  • Lies die Zustandsspalte, bevor du eine Verbindung für kaputt erklärst: TIME-WAIT gehört zum normalen Schließen.
  • Sieh dir die Zähler fürs erneute Senden an (ss -to), bevor du der Anwendung die Schuld an einer lahmen Übertragung gibst.
  • Verlass dich nicht auf TCP als Schutz: Verschlüssele sensible Verbindungen mit TLS und prüfe die Zertifikate.
  • Halte Ports und ihren Zweck in deiner Dokumentation fest, ohne die Adressen zu veröffentlichen.
  • Denk daran, dass „zuverlässig“ heißt „kommt vollständig und in der richtigen Reihenfolge an“, nicht „kommt schnell an“.
  • Öffne bei HTTP/3-Diensten Port 443 auch für UDP und setze Keepalives auf langlebigen Verbindungen.

Primärquellen

Die Quellen belegen die technischen Kernaussagen. Einordnung und Prüfliste sind unsere eigene Arbeit.

  1. W. Eddy (ed.), IETFRFC 9293, Transmission Control Protocol (TCP)
  2. M. Allman, V. Paxson, E. Blanton, IETFRFC 5681, TCP Congestion Control
  3. J. Touch, A. Mankin, R. Bonica, IETFRFC 5925, The TCP Authentication Option
  4. E. Rescorla, IETFRFC 8446, The Transport Layer Security (TLS) Protocol Version 1.3
  5. Linux man-pages projectss(8)
  6. J. Postel, IETFRFC 768, User Datagram Protocol
  7. J. Iyengar, M. Thomson (eds.), IETFRFC 9000, QUIC: A UDP-Based Multiplexed and Secure Transport

Auf dieser Seite gibt es keine Werbung und keine Partnerlinks.