Netzwerk-Know-how (tecCHANNEL COMPACT) Kapitel 6: UDP und TCP

Veröffentlicht: 22. Jun 2005

Von PROF. DR. STEPHAN EULER

In diesem Beitrag behandeln wir die Transportprotokolle UDP und TCP, die die Prototypen Datagramm-Dienst und stromorientierten Dienst über IP darstellen.

Auf dieser Seite

In diesem Beitrag

Dn151200.ACDCF196BC98A92A7E35715F19C8C405(de-de,TechNet.10).png UDP

Dn151200.ACDCF196BC98A92A7E35715F19C8C405(de-de,TechNet.10).png TCP

Dn151200.ACDCF196BC98A92A7E35715F19C8C405(de-de,TechNet.10).png Segmentierung

Dn151200.ACDCF196BC98A92A7E35715F19C8C405(de-de,TechNet.10).png Verbindungsaufbau

Dn151200.ACDCF196BC98A92A7E35715F19C8C405(de-de,TechNet.10).png Sliding Window

Dn151200.ACDCF196BC98A92A7E35715F19C8C405(de-de,TechNet.10).png Schätzung der RTT

Dn151200.ACDCF196BC98A92A7E35715F19C8C405(de-de,TechNet.10).png Flusskontrolle

Dn151200.ACDCF196BC98A92A7E35715F19C8C405(de-de,TechNet.10).png Überlastkontrolle

Bisher haben wir betrachtet, wie Pakete von einem Rechner zu einem anderen Rechner geschickt werden. Die eigentliche Kommunikation erfolgt zwischen Anwendungen, das heißt Prozessen auf den jeweiligen Betriebssystemen.

Beispiele für Anwendungen sind Terminalprogramme wie Telnet, Datentransfer über FTP, E-Mail-Programme sowie Internet-Browser.

Diese Anwendungen kommunizieren mit einem entsprechenden Partner auf einem entfernten Rechner. Man spricht daher von Ende-zu-Ende-Protokollen und der Transportschicht. Diese Protokolle sind Mittler zwischen der Vermittlungsschicht und den Anwendungen. Sie müssen mit den Möglichkeiten der Vermittlungsschicht ein den Anforderungen der Anwendungen genügendes Protokoll realisieren. So ist beispielsweise für den Dateitransfer eine zuverlässige Verbindung über das unzuverlässige Best-Effort-IP erforderlich.

Allerdings stellen verschiedene Anwendungen unterschiedliche Anforderungen. So benötigt FTP eine zuverlässige Verbindung zur effizienten Übertragung großer Datenmengen. Ein Terminalprogramm liefert demgegenüber nur kleine Datenmengen (ein Zeichen für einen Tastendruck), die aber möglichst sofort geschickt werden sollen. Einige Anwendungen wie eine Video-Konferenz können gelegentliche Datenverluste akzeptieren, benötigen aber eine große Bandbreite mit einer über die Zeit relativ konstanten Qualität.

Erst auf der Ebene der Ende-zu-Ende-Protokolle können derartige Anforderungen konkretisiert werden. Durch diese Arbeitsteilung wird das Protokoll der Vermittlungsebene IP entlastet. IP stellt nur die notwendige Basisfunktionalität zur Verfügung und kann damit als Grundlage für unterschiedlichste Anwendungen dienen. Würde umgekehrt IP beispielsweise einen Schutz gegen Paketverluste gewährleisten, müssten verloren gegangene Pakete erneut geschickt werden. Durch die daraus resultierende Verzögerung wäre das Protokoll für Echtzeitanwendungen weniger geeignet.

Im Folgenden behandeln wir die Transportprotokolle UDP und TCP, die die Prototypen Datagramm-Dienst und stromorientierten Dienst über IP darstellen. Im Kapitel 10 wird ein Beispiel für einen Anfrage/Antwort-Dienst vorgestellt.

Dn151200.590B5404BFEA7F06684DB47B00539355(de-de,TechNet.10).png Zum Seitenanfang

UDP

Das UDP - User Datagram Protocol - ist ein einfaches Datagramm-Protokoll. Im Prinzip erweitert es lediglich den Host-zu-Host-Dienst um die Adressierung einer Anwendung. Auf einem Rechner können gleichzeitig mehrere Anwendungen oder mehrere Instanzen einer Anwendung aktiv sein. Daher wird eine eindeutige Kennung für jede Anwendung benötigt.

Das Betriebssystem stellt zu diesem Zweck Kommunikationspunkte - die Ports - zur Verfügung. Eine Anwendung meldet sich an einem Port an und erhält von nun an vom Betriebssystem alle Nachrichten für diesen Port. Dieser ist eine Abstraktion eines Kommunikationspunktes. Wie der Port konkret realisiert wird, bleibt dem Betriebssystem überlassen. Wesentlich ist, dass die UDP-Pakete die entsprechende Portadresse enthalten. Für diese Adressen stehen im UDP-Header 16 Bit zur Verfügung, wobei der Header sowohl Quell- als auch Zielport enthält. Zur Vollständigkeit ist der Aufbau der UDP-Pakete in Tabelle 7.1 dargestellt. Neben den Portadressen enthält der Header nur noch Felder für eine optionale Prüfsumme sowie die Längeninformation.

Ein UDP-Paket wird dann für die Übermittlung in ein IP-Paket gepackt. Dieses trägt die IP-Adresse des Zielrechners. Dort angekommen, wird das IP-Paket entpackt, und die Portadressen werden dem UDP-Header entnommen.

Insgesamt bildet das Paar <IP-Adresse, Portadresse> die vollständige Adresse der Anwendung. Das IP-Paket enthält sowohl für Sender als auch Empfänger diese beiden Informationen.

Dn151200.EC15E00F9B5E3A387ACB649347910668(de-de,TechNet.10).png

Tabelle 7.1: UDP Paket-Format

Jeder der beiden Prozesse muss in irgendeiner Form die Portadressen des jeweiligen Partners kennen. Einige Dienste verwenden daher feste, öffentlich bekannte Portnummern. In Tabelle 7.2 sind für einige Anwendungen die Portnummern aufgelistet. Eine umfangreiche Liste finden Sie auf der Online-Seite www.iana.org/ assignments/port-numbers. In dem tecCHANNEL-Artikel „Ports im Überblick" (webcode: p901) sind die wichtigsten Portnummern und -funktionen enthalten. In manchen Fällen benutzen Anwendungen derartige wohl bekannte Portnummern nur, um den Kontakt aufzunehmen und für die weitere Kommunikation einen eigenen Port auszuhandeln.

Dn151200.67DAA70E681DCCEBE88762BB959A0C31(de-de,TechNet.10).png

Dn151200.590B5404BFEA7F06684DB47B00539355(de-de,TechNet.10).png Zum Seitenanfang

TCP

UDP ist letztlich nur ein Multiplexer zwischen verschiedenen Anwendungen und dem IP-Protokoll. Es bietet keine funktionalen Erweiterungen gegenüber dem unzuverlässigen Paketdienst. Viele Anwendungen benötigen aber eine zuverlässige Verbindung. Das wichtigste Protokoll für diese Fälle ist TCP (Transmission Con-trol Protocol). TCP realisiert einen zuverlässigen, Verbindungsorientierten Byte-Strom. Anwendungen, die auf TCP aufsetzen, werden dadurch von vielen Implementierung sdetails entlastet. Wesentliche Eigenschaften von TCP sind:

  • Verbindung saufbau
  • zuverlässige Übertragung
  • Vollduplex-Byte-Strom
  • Flusskontrolle (Schutz des Empfängers vor zu vielen Daten)
  • Überlastkontrolle (Schutz des Netzes vor zu vielen Daten)
  • Multiplex für mehrere Anwendungen (analog zu UDP)

Die große Herausforderung für TCP ist, über einen unzuverlässigen Paketdienst und ein komplexes, sich ständig veränderndes Netz eine zuverlässige Verbindung mit möglichst hohem Datendurchsatz und geringer Verzögerung zu realisieren. TCP benutzt den uns aus Kapitel 3 bekannten Sliding-Window-Algorithmus. Der Basisalgorithmus wird allerdings an mehreren Punkten erweitert, um der wesentlich schwierigeren Situation Rechnung zu tragen.

Dn151200.590B5404BFEA7F06684DB47B00539355(de-de,TechNet.10).png Zum Seitenanfang

Segmentierung

Aus Sicht der Anwendung stellt TCP einen Byte-Strom dar. Das heißt, die Anwendung kann einzelne Bytes schreiben oder lesen. Andererseits überträgt IP Pakete. Es ist wenig effizient, jedes Byte stets in einem eigenen IP-Paket zu verschicken. Das Verhältnis Nutzdaten zu Header-Daten ist dann sehr ungünstig. Daher setzt TCP den Byte-Strom in eine Folge von so genannten Segmenten um. Den gesamten Ablauf für eine Richtung zeigt Bild 1

Dn151200.1CF5178554BB65E4DB77ED0FAE20219B(de-de,TechNet.10).png

Bild 1: Segmentierung des Byte-Stroms in TCP für eine Richtung

Auf der Sendeseite sammelt TCP zunächst die geschriebenen Bytes in einem Puffer. Aus dem Puffer werden dann Bytes zu Segmenten zusammengefasst. Im Sinne der Netzwerknutzung sind möglichst große Segmente wünschenswert, um ein gutes Verhältnis von Nutzdaten zu Header-Daten zu erzielen.

Andererseits führen große Segmente zu längeren Wartezeiten. Außerdem gibt es im zu Grunde liegenden Netz eine Beschränkung der Paketgröße. Insgesamt verwendet TCP folgende Kriterien für das Versenden des nächsten Segments:

  • Die maximale Segmentgröße (Maximum Segment Size, MSS) ist erreicht. Zweckmäßigerweise wird MSS so gewählt, dass IP das Segment nicht fragmentieren muss.
  • Die Anwendung wünscht explizit den sofortigen Versand (Push-Operation). Beispiel: Terminalanwendungen wie Telnet erfordern die wenig effiziente, sofortige Weitergabe jedes Tastendrucks.
  • Der Timer für die Zeit zum Aufsammeln ist abgelaufen.

Das Format der TCP-Segmente zeigt Tabelle 7.3. Die Information über die Segmentierung steckt im Feld Sequence Number. Diese Zahl bezeichnet den Index des ersten Bytes im Datenfeld. Der Header enthält keine Information zu der Länge des Datenfelds. Die Anzahl der Daten berechnet der Empfänger aus der Gesamtlänge des IP-Pakets abzüglich der beiden Header.

Dn151200.6FF3550E56978EF33B48ADBD24B8B9D8(de-de,TechNet.10).png

Wie bei UDP enthält der Header die beiden Portadressen, die Länge des Headers sowie eine Prüfsumme. In dem Feld Flags stehen Steuerinformationen. Hier kann beispielsweise das Flag URG gesetzt werden, um den ersten Teil der Daten als dringend zu kennzeichnen. Der Zeiger Urgent Pointer deutet dann auf das erste Byte, das nicht mehr zu dem dringenden Teil gehört. Die Bedeutung der anderen Felder werden wir im weiteren Verlauf des Beitrags behandeln.

Dn151200.590B5404BFEA7F06684DB47B00539355(de-de,TechNet.10).png Zum Seitenanfang

Verbindungsaufbau

TCP ist ein Verbindungsorientierter Dienst. Die Kommunikation beginnt mit einer Phase zum Aufbau einer virtuellen Verbindung. Diese existiert nur auf der Ebene von TCP und nicht im physikalischen Netz. Sie geht von einer Anwendung auf einem Rechner zu einer anderen Anwendung auf einem zweiten Rechner. Die beiden Endpunkte sind jeweils durch Portadresse und IP-Adresse gegeben. Insgesamt ist die Verbindung damit durch die vier Werte <IP-Adressel, Portadressel, IP-Adresse2, Portadresse2> definiert.

Eine wesentliche Aufgabe der beiden Partner ist es, sich über die Segmentnummern zu einigen. Die Designer von TCP hatten entschieden, dass für eine neue Verbindung zufällige Startwerte zu wählen sind. Damit soll verhindert werden, dass eventuelle Irrläufer aus einer vorherigen Verbindung der beiden Anwendungen die neue Verbindung stören. Durch die zufälligen Startwerte lassen sich diese alten Pakete mit großer Wahrscheinlichkeit an ihren nicht mehr passenden Segmentnummern erkennen. Zum Verbindungsaufbau dient ein Drei-Wege-Handshake. Dabei werden die Flags im Header zum Informationsaustausch genutzt. Der Ablauf ist wie folgt:

  1. Anwendung A schickt ein Segment mit dem Flag S YN und seiner Segmentnummer NA.
  2. Anwendung B bestätigt den Eingang durch ein Segment mit den Flags SYN undACK. Gleichzeitig setztB dieAcknowledgeNumber auf NA+1, um anzugeben, welches Byte als Nächstes zu erwarten ist. Schließlich wird die eigene Segmentnummer NB zufällig ausgewählt und eingetragen.
  3. Anwendung A erhält die Bestätigung und schickt daraufhin ebenfalls eine Bestätigung mit ACK und NB+1 als Acknowledge Number.

Dn151200.590B5404BFEA7F06684DB47B00539355(de-de,TechNet.10).png Zum Seitenanfang

Sliding Window

Für eine zuverlässige Verbindung verlangt der Sender für jedes geschickte Segment eine Bestätigung. Diese kann in einem eigenen Segment stehen oder Teil eines Segments mit Daten sein. Wir haben bereits in der Diskussion zum einfachen Stop-and-Wait-Algorithmus gesehen, dass das Netzwerk schlecht ausgelastet ist, wenn erst nach Erhalt der Bestätigung das nächste Paket auf die Reise geht. Diese Situation ist bei einer Verbindung im Internet noch verschärft. Die Antwortzeiten sind hier recht groß, insbesondere kann ein Paket sich zum Beispiel durch Überlastung einer Teilstrecke deutlich verzögern. Daher muss der Sender beim Ausbleiben einer Bestätigung lange warten, bis er sicher ist, dass das Segment verloren gegangen ist.

TCP nutzt daher den Sliding-Window-Algorithmus, und ein Sender schickt mehrere Segmente direkt nacheinander. Anhand der eingehenden Bestätigungen kann er verfolgen, welche Segmente angekommen sind. Bleibt eine Bestätigung aus, wiederholt er die alten Segmente ab dem letzten bestätigten Segment.

Dn151200.590B5404BFEA7F06684DB47B00539355(de-de,TechNet.10).png Zum Seitenanfang

Schätzung der RTT

Im Internet mit den unterschiedlichsten Arten von Verbindungen, die noch dazu zeitlichen Schwankungen unterworfen sind, ist die Wahl der Wartezeit auf Bestätigungen schwierig. Ein fester Wert für den Timeout müsste an Verbindungen mit großer RTT ausgerichtet sein und wäre damit in vielen Fällen zu pessimistisch.

Daher wird bei TCP die Laufzeit adaptiv geschätzt. Der Sender misst dazu die Zeit vom Versand bis zum Erhalt der Bestätigung und benutzt diesen Wert als aktuelle Schätzung RTTa. Diese aktuelle Schätzung kann sehr stark schwanken. Um diese Schwankungen auszugleichen, wird der Schätzwert für RTT als gleitender Mittelwert zwischen dem alten Wert und dem aktuellen Wert in der Form

Dn151200.416C4BF81A3D59A01B618B59B2FD71F4(de-de,TechNet.10).png

gemittelt. Der Koeffizient a bestimmt, wie schnell sich die Schätzung an Änderungen adaptiert. Bei einem kleinen Wert von a geht der alte Wert nur zu einem geringen Anteil in die Berechnung ein, so dass sich Änderungen sehr schnell auswirken. Umgekehrt bewirkt ein großer Wert, das heißt a nahe an 1, dass die Änderungen langsam erfolgen.

Typische Werte liegen im Bereich von 0,8 bis 0,9. TCP benutzt dann als Wert für den Timeout das Doppelte der geschätzten RTT. Der beschriebene Algorithmus stammt aus der ursprünglichen TCP-Spezifikation. Mittlerweile sind Verfeinerungen des Algorithmus im Einsatz, die unter anderem die Schwankung der Messwerte als Maß für die Zuverlässigkeit der Schätzung benutzen.

Dn151200.590B5404BFEA7F06684DB47B00539355(de-de,TechNet.10).png Zum Seitenanfang

Flusskontrolle

Auf Seiten des Empfängers besteht die Gefahr, dass die ankommenden Daten nicht schnell genug von der Anwendung aus dem Empfangspuffer gelesen werden. Dann füllt sich der Puffer immer mehr, und irgendwann ist kein Platz mehr für weitere Daten. Der Empfänger kann den Empfang neuer Segmente nicht mehr bestätigen, und der Sender muss sie später nochmals schicken. Ohne besondere Vorkehrungen wäre in einem solchen Fall viel unnötiger Netzverkehr die Folge. Daher verfügt TCP über einen Mechanismus, mit dem der Empfänger die Übertragungsgeschwindigkeit des Senders steuern kann.

Der Empfänger benutzt dazu das Feld Advertised Window im TCP-Header. In seinen Bestätigungsmeldungen (oder eigenen Datensegmenten) trägt er in diesem Feld ein, wie viele Bytes er zurzeit noch aufnehmen kann. Der Sender schickt dann bis zur nächsten Bestätigung nur noch maximal so viele Bytes. Wenn beim Empfänger der Platz abnimmt, weil die lokale Anwendung die Daten momentan nur sehr langsam oder gar nicht mehr liest, reduziert er die Größe im Feld Advertised Window und bremst damit den Sender.

Im Extremfall - wenn der Puffer vollständig gefüllt ist - meldet er den Wert 0 und signalisiert damit, dass er zurzeit keine Daten mehr aufnehmen kann. In diesem Fall schickt der Sender trotzdem weiterhin in regelmäßigen Abständen Segmente mit nur einem Daten-Byte. Solange der Empfänger nicht in der Lage ist, Daten aufzunehmen, ignoriert er die Segmente. Hat er allerdings wieder Platz, kann er das Byte übernehmen und in der Bestätigung ein größeres Advertised Window angeben. Auf diese Art wird der Transfer wieder aufgenommen, ohne dass beim Empfänger eine spezielle Vorgehensweise implementiert sein muss. Dieses Konzept, bei dem die Intelligenz beim Sender liegt, wird mit dem allgemeinen Ausdruck smart sender/ dumb receiver rule bezeichnet.

Dn151200.590B5404BFEA7F06684DB47B00539355(de-de,TechNet.10).png Zum Seitenanfang

Überlastkontrolle

Ohne weitere Maßnahmen kann TCP leicht zu einer Überlastung des Netzes führen. Dass TCP im Fall der Netzüberlastung, wenn Segmente verloren gehen, mit erhöhter Aktivität reagiert, indem es die Segmente erneut sendet, ist dann besonders kritisch. Damit verschlimmert sich eine Überlast im Netz noch weiter, und es kann zu einem Kollaps kommen. Um die Situation zu verbessern, wurde Ende der achtziger Jahre eine Überlastkontrolle in TCP eingeführt. Sie basiert auf der Schätzung der Netzbelastung durch einen Sender. Auf der Basis der beobachteten Paketübertragungen und Paketverluste steuert ein Sender selbstständig seine Übertragungsgeschwindigkeit.

Ein prinzipielles Problem dabei ist, dass er nur indirekt Informationen über das Netz erhält. Um das Optimum zu ermitteln, muss er die Grenzen herausfinden. Diese entdeckt er nur, indem er sie überschreitet. Er muss zunächst die Übertragungsrate möglichst weit erhöhen, bis er irgendwann an ein Limit stößt. Dann nimmt er die Rate zurück und nähert sich sozusagen vorsichtig von unten wieder dem Optimum. Durch diese gezielte Überschreitung des Optimums wird zusätzlich Verkehr erzeugt. Daher ist es wichtig, nach einer Überschreitung schnell wieder auf einen sicheren Wert zurückzugehen. Umgekehrt kann das Herantasten an das Optimum langsam erfolgen.

Auf diesen Gedanken beruht das Konzept Additive Increase / Multiplicative De-crease. Der Sender führt ein Überlastfenster, das festlegt, wie viele Daten maximal bis zur nächsten Bestätigung gesendet werden dürfen. Diese Größe schöpft er nur aus, wenn der Empfänger entsprechende Aufnahmekapazität signalisiert hat. Geht ein Segment verloren, vermutet der Sender eine Überlastung im Netz. In diesem Fall reduziert er sein Überlastfenster auf die Hälfte.

Umgekehrt zeigt ihm ein ACK an, dass ein Segment gut angekommen ist. Wenn sämtliche Segmente in einem Sliding-Window-Intervall bestätigt wurden, erhöht er das Überlastfenster um einen kleinen Betrag. Das Fenster wächst langsam an, bis irgendwann erneut das Limit erreicht ist. Dann wird es wieder auf die halbe Größe reduziert. Dieser Zyklus des langsamen Anwachsens und schnellen Schrumpfens wiederholt sich immer wieder. Die Priorität liegt auf dem Schutz des Netzes vor Überlast.

Das typische Verhalten des Überlastfensters zeigt Bild 2. Die Werte wurden mittels eines einfachen Simulationsprogramms erzeugt. In der Simulation wird eine Kapazität vorgegeben. Das Überlastfenster wächst bis zum Erreichen der Kapazitätsgrenze linear an. Nach jedem Überschreiten wird das Fenster wieder auf die Hälfte des letzten Wertes reduziert. Der Wert für die Kapazitätsgrenze - im Bild jeweils als Punkt eingetragen - wird in der Simulation nach jedem Zeitschritt um einen zufälligen Wert verändert.

Dn151200.3CC278551CE25C66285C3A3EE1619C82(de-de,TechNet.10).png

Bild 2: Regelung der Fenstergröße durch Lastkontrolle bei simulierter Kapazitätsgrenze (gestrichelte Linie)

Eine besondere Situation besteht am Anfang der Verbindung. Hier hat der Sender noch keinerlei Informationen über das Netz. Deshalb befindet er sich in einem Dilemma: Beginnt er mit der vollen Fenstergröße, riskiert er eine Überlastung. Andererseits ist ein langsames, lineares Steigern unter Umständen zu pessimistisch. Daher verwendet der Sender einen Slow-Start-Ansatz (im Gegensatz zu Full-Start mit der vollen Fenstergröße). In diesem Fall erhöht er das Fenster bereits nach jedem ACK. Wenn er vor dem Timeout n Segmente geschickt hat, wird im Erfolgsfall das Fenster auch n mal erhöht und nicht nur einmal wie im oben beschriebenen Additive-Increase-Ansatz. In Summe verdoppelt sich dadurch die Anzahl der gesendeten Segmente pro RTT Das Verfahren ist sozusagen das Gegenstück zum Multiplicative Decrease mit umgekehrter Tendenz.

© www.tecCHANNEL.de

Dn151200.590B5404BFEA7F06684DB47B00539355(de-de,TechNet.10).png Zum Seitenanfang

| Home | Technische Artikel | Community