19 Punkte von GN⁺ 2025-11-16 | 1 Kommentare | Auf WhatsApp teilen
  • TCP (Transmission Control Protocol) ist das zentrale Protokoll des Internets, das selbst in instabilen Netzwerkumgebungen eine zuverlässige und geordnete Datenübertragung ermöglicht
  • Während IP nur für die Datenübermittlung zwischen Hosts zuständig ist, übernimmt TCP die prozessbasierte Kommunikation über Ports sowie Fehlerbehebung, Neuübertragung und Reihenfolgenkontrolle
  • Durch Flow Control und Congestion Control wird gesteuert, dass weder die Grenzen des Empfangspuffers noch die verfügbare Netzwerkbandbreite überschritten werden
  • Anhand von in C implementierten einfachen TCP-Server- und HTTP-Server-Beispielen werden das Erzeugen von Sockets, Binden, Lauschen, das Akzeptieren von Verbindungen sowie Sende- und Empfangsabläufe konkret erklärt
  • Die interne Struktur von TCP mit Sequenz- und ACK-Nummern, Window, Checksum und Flags (SYN/ACK/FIN/RST) ist eine zentrale Grundlage für den stabilen Betrieb des heutigen Internets

Notwendigkeit und Rolle von TCP

  • IP ist nur für die Übermittlung von Paketen zwischen Hosts zuständig; für die Kommunikation zwischen Prozessen ist eine Transportschicht wie TCP/UDP erforderlich
    • Die IP-Adresse wird mit einem „Gebäude“ verglichen, der Port mit einer „Wohnung“; jede Anwendung kommuniziert, indem sie an einen Port gebunden wird
  • TCP verbirgt Netzwerkinstabilitäten wie Paketverlust, Duplikate und vertauschte Reihenfolge und gewährleistet durch Neuübertragung und Checksum Zuverlässigkeit
  • Router bleiben einfach, und die Zuverlässigkeit wird an den beiden Endpunkten der Kommunikation verarbeitet, wodurch die Komplexität der Netzwerkinfrastruktur reduziert wird
  • Dank dieser Struktur funktionieren wichtige Internetdienste wie HTTP, SMTP und SSH stabil

Flow Control und Congestion Control

  • Die Empfangsseite speichert Daten vorübergehend über den Receive Buffer des Kernels; dessen Größe wird mit net.ipv4.tcp_rmem festgelegt
  • Die Sendeseite erhält über das Feld Window die vom Empfänger zulässige Datenmenge und passt die Übertragungsmenge entsprechend an
  • Um Congestion zu verhindern, die durch Unterschiede in der verfügbaren Bandbreite im gesamten Netzwerk entsteht, verwendet TCP Algorithmen zur Congestion Control
    • Ausgelöst durch das Ereignis des Congestion Collapse von 1986 wurde ein Back-off-Mechanismus hinzugefügt

Beispiele für TCP-Server und HTTP-Server

  • Ein in C geschriebener einfacher TCP-Echo-Server nimmt Eingaben des Clients entgegen und sendet sie mit vorangestelltem „you sent:“ zurück
    • Verwendet werden die Berkeley-Sockets-API-Aufrufe socket(), bind(), listen(), accept(), send() und recv()
    • Während sich der Server in sleep() befindet, warten die Daten des Clients im Receive Buffer und werden anschließend der Reihe nach verarbeitet
  • In einem einfachen HTTP/1.1-Server-Beispiel werden Anfragen über eine TCP-Verbindung angenommen und ein HTTP/1.1 200 OK-Header sowie ein Body gesendet
    • Die Anzahl der Anfragen wird mit i gezählt; bei einer Anfrage mit curl localhost:8080 wird eine Antwort in der Form „[1] Yo, I am a legit web server“ ausgegeben

Struktur von TCP-Segmenten und zentrale Felder

  • Ein TCP-Segment besteht aus Quell- und Zielport, Sequenznummer, ACK-Nummer, Window-Größe, Checksum und Flags
    • Ports sind jeweils 16 Bit breit, sodass bis zu 64K Ports verwendet werden können
    • Eine Verbindung wird durch ein 5-Tupel identifiziert: (Protokoll, Quell-IP, Quellport, Ziel-IP, Zielport)
  • Die Sequenznummer gibt den Bereich der übertragenen Bytes an, die ACK-Nummer die bereits vollständig empfangenen Bytes
    • Wenn Daten fehlen, bleibt das ACK an dieser Stelle stehen und wird nach der Neuübertragung als kumulatives ACK aktualisiert
  • Flag-Bits steuern den Verbindungszustand
    • SYN/ACK stellen über den 3-Way-Handshake eine Verbindung her
    • FIN beendet die Verbindung über einen 4-Way-Handshake
    • RST trennt die Verbindung bei abnormalem Ende oder Fehlern sofort
  • Das Window-Feld zeigt die empfangbare Datenmenge an; mit dem Befehl ss lässt sich der Pufferstatus (rb131072, tb16384) prüfen
  • Die Checksum dient der Fehlererkennung durch Summierung in 16-Bit-Einheiten innerhalb des Segments

Fazit

  • TCP garantiert Zuverlässigkeit, Reihenfolge und Integrität und unterstützt Anwendungen dabei, auch in instabilen Internetumgebungen korrekt zu funktionieren
  • Während vor Jahrzehnten schon die Übertragung einiger KB schwierig war, ist heute selbst 4K-Streaming alltäglich geworden
  • Die Präzision von Design und Implementierung von TCP, die diese stabile Kommunikation ermöglicht, bildet die Grundlage für das kontinuierliche Wachstum des Internets

1 Kommentare

 
GN⁺ 2025-11-16
Hacker-News-Kommentare
  • Wenn man versucht, auf einer unzuverlässigen Datagramm-Schicht einen zuverlässigen Datenstrom aufzubauen, erhält man am Ende etwas, das TCP fast entspricht
    Die anfänglichen Grenzen von TCP waren eine kleine Fenstergröße, unzureichende Behandlung verlorener Pakete und die Beschränkung auf nur einen einzelnen Stream
    Um diese Probleme zu lösen, entstanden SCTP und QUIC
    Algorithmen zur Staukontrolle sind kein Teil des Protokolls, sondern Code, der auf beiden Seiten jeder Verbindung läuft
    Frühe Algorithmen (Reno, Vegas usw.) waren einfach, aber ausreichend wirksam, und danach wurde weiter zu großen Puffern, langen RTTs, Fairness usw. geforscht

    • Ich denke auch, dass Webentwickler eine Mitschuld daran tragen, dass Multi-Streaming nicht gut genutzt wurde
      Früher habe ich in JavaScript eine Bibliothek geschrieben, mit der sich mehrere Downloads innerhalb eines Streams mit Priorisierung und Abbruchfunktionen steuern ließen
      Mit einem GreaseMonkey-Skript ließ ich die Thumbnails einer Dating-Seite im Hintergrund vorab laden, abhängig von der Scroll-Position
      Dadurch wurde letztlich die Serverlast gesenkt und zugleich die Benutzererfahrung verbessert
      Lustigerweise habe ich dieses Skript mit einem Match geteilt, und mit dieser Person bin ich bis heute zusammen — es war gewissermaßen Tinder vor Tinder
    • Als TCP entwickelt wurde, dominierte noch das vom Telefonnetz geprägte Denken in Leitungsvermittlung (circuit switching)
      TCP ist eine Struktur, die über einem paketvermittelten Netz eine virtuelle Leitung bereitstellt; die Idee, Zuverlässigkeit durch Wiederübertragung umzusetzen, stammt aus dem französischen Netzwerk Cylades
    • Einer der grundlegenden Mängel von TCP ist seine Unabsicherbarkeit
      Ein Angreifer kann überall im Netzwerk Daten injizieren oder mit einem RST-Paket die Verbindung trennen
      Wenn man RST per Firewall blockiert, steigt zwar die Stabilität, aber Desynchronisierungsangriffe durch gefälschte Sequenznummern bleiben weiterhin möglich
      Daher muss jede Anwendung über eine separate Verbindung eine Resume-Funktion implementieren und trägt zugleich das Problem von TCP Slow Start mit sich
      Außerdem halte ich schon das Konzept, Adressen und Ports getrennt zu behandeln, für ineffizient
    • Manche Anwendungen funktionieren auch mit einer einzelnen TCP-Verbindung vollkommen gut
      Bei DNS over TLS (DoT) kann man zum Beispiel über eine TCP-Verbindung mehrere Abfragen gleichzeitig senden und Antworten unabhängig von der Reihenfolge empfangen
      Das ist effizienter und rücksichtsvoller, als mehrere Verbindungen zu öffnen
      Ob QUIC schneller ist, weiß ich nicht, aber die Serverunterstützung ist noch begrenzt
      HTTP/1.1-Pipelining macht etwas Ähnliches, aber die Antworten kommen der Reihe nach
    • Dass der Algorithmus zur Staukontrolle bei TCP außerhalb des Protokolls liegt, war damals äußerst innovativ
      Viele Universitätsvorlesungen betonen diesen Punkt jedoch nicht, sodass oft der Irrtum entsteht, TCP habe nur einen einzigen Algorithmus
  • Ich würde gern fragen, ob hier jemand eine besondere Zuneigung zu SCTP hat
    SCTP ist ein Protokoll, das die Nachrichtenorientierung von UDP mit der Zuverlässigkeit von TCP verbindet und Multi-Streaming sowie Multihoming unterstützt
    Es kann mehrere unabhängige Streams parallel übertragen, sodass sich der Text und die Bilder einer Webseite gleichzeitig senden lassen
    Details dazu unter Wikipedia: Stream Control Transmission Protocol

    • SCTP löst nur die Hälfte des Problems und führt mehrere neue Mängel ein
      Am Ende ist die beste Antwort eine Zuverlässigkeitsschicht über UDP, also QUIC
    • Als jemand, der gern BSD nutzt und mit Erlang arbeitet, liebe ich SCTP sehr
  • Ich habe mich gefragt, ob man nur mit IP direkt Pakete senden kann
    Ich dachte, zwischengeschaltete Router würden Pakete verwerfen, die weder TCP noch UDP sind

    • Man kann IP-Pakete direkt manipulieren und senden
      Bei IPv4 genügt es, aus der Liste der IANA-Protokollnummern einen Wert zwischen 0 und 255 festzulegen
      Core-Router prüfen dieses Feld nicht, NAT- oder ISP-Geräte können es aber prüfen
      Zwischen zwei Linux-Servern ist sogar mit experimentellen Nummern (253, 254) Kommunikation möglich
    • ICMP sollte man ebenfalls nicht vergessen. Unter IPv6 ist es noch wichtiger
      Protokolle wie IPsec, GRE und L2TP sind ebenfalls weder TCP noch UDP
      In Unternehmensnetzen mit Firewalls oder NAT können beliebige Protokolle blockiert werden
      NAT hat das Ende-zu-Ende-Prinzip gebrochen, und am Ende begannen die Leute, alles auf TCP oder UDP oder sogar auf HTTP zu legen
    • Ohne NAT oder Load Balancer gibt es kein Problem, aber da sie heute verbreitet sind, könnte IPv6 die bessere Wahl sein
    • Router sind Schicht-3-Geräte und kümmern sich nicht darum, ob es TCP oder UDP ist
      Es hat allenfalls Auswirkungen darauf, dass die Entropie des ECMP-Hashs sinkt
      Entscheidend ist letztlich, ob die Gegenstelle dieses Protokoll versteht
    • TCP und UDP sind nur IP-Payloads, und Router interpretieren sie nicht
      Portnummern sind lediglich Kennungen für Dienste innerhalb eines Knotens
  • RUDP (Plan9) war ein hervorragender Kompromiss zwischen TCP und UDP
    Siehe Reliable User Datagram Protocol

  • Dadurch, dass TCP zum Standard wurde, wurde es selbst dann zwangsläufig verwendet, wenn weder Zuverlässigkeit noch Reihenfolgegarantie nötig waren
    Jetzt, da sich HTTP/3 (auf QUIC-Basis) verbreitet, könnte sich die Lage verbessern
    QUIC ist allerdings deutlich komplexer, und seine Stärke ist nur für einen Teil der Nutzer wirklich nützlich
    Eine einfache Verschlüsselungsschicht im Stil von UDP + WireGuard könnte die bessere Alternative sein

  • TCP ist eine der großen Erfindungen der Menschheit, hat aber die Herrschaft des halbverbindungsorientierten Netzwerks (NAT-basiert) nicht vorhergesehen

    • Dann kam die Frage auf: „Meinst du NAT?“
    • Wenn man ins Jahr 1981 zurückginge und sagte: „Lasst uns statt weltweit eindeutiger Adressen nur Adressen aus einem begrenzten Bereich verwenden und einige Knoten unzugänglich machen“,
      hätten die Ingenieure damals wohl gefragt, warum man es absichtlich so kompliziert machen sollte
      Letztlich stammen die heutige asymmetrische Link-Struktur und die Trennung zwischen Client und Server aus genau dieser Denkweise
  • Der Algorithmus zur Staukontrolle von TCP hat interessante Effekte, die vielen Entwicklern nicht bekannt sind
    Wenn man auf einer neuen Verbindung Daten sendet, ist die anfängliche Übertragung langsam, und der Geschwindigkeitsanstieg wird durch die Latenz bestimmt
    In Rechenzentren kann schon eine Verringerung der RTT um einige Mikrosekunden zu deutlich höherer Geschwindigkeit führen
    Die meisten TCP-Stacks berechnen den Geschwindigkeitsanstieg nicht pro Byte, sondern pro Segment, sodass man mit Jumbo Frames sechsmal schneller ansteigen kann
    AWS investiert aus diesem Grund viel in geringe Switching-Latenz und Unterstützung für Jumbo Frames
    Experten nehmen solche Feinabstimmungen vor, aber die meisten wundern sich nur, warum über einen 10-Gbps-Link keine 10 Gbps erreicht werden

  • Ein eigenes Protokoll über IP zu bauen war sehr einfach
    Noch vor 15 Jahren konnte man in Python experimentieren, indem man Pakete direkt zusammensetzte