Transmission Control Protocol/Datenübertragung: Unterschied zwischen den Versionen
K Textersetzung - „Man-Pages“ durch „Man-Page“ |
|||
(11 dazwischenliegende Versionen desselben Benutzers werden nicht angezeigt) | |||
Zeile 4: | Zeile 4: | ||
== TCP-/IP-Segment-Größe == | == TCP-/IP-Segment-Größe == | ||
; Ein TCP-Segment hat typischerweise eine Größe von maximal 1500 Bytes. | ; Ein TCP-Segment hat typischerweise eine Größe von maximal 1500 Bytes. | ||
* Ein TCP-Segment muss jedoch in die darunter liegende Übertragungsschicht passen, das [[Internetprotokoll]] (IP); siehe hierzu auch [[Maximum Transmission Unit]] (MTU). | * Ein TCP-Segment muss jedoch in die darunter liegende Übertragungsschicht passen, das [[Internetprotokoll]] (IP); siehe hierzu auch [[Maximum Transmission Unit]] (MTU). | ||
[[IP-Paket]]e wiederum sind zwar theoretisch bis 65.535 Bytes (64 [[Kibibyte|KiB]]) spezifiziert, werden aber selbst meist über [[Ethernet]] übertragen, und bei Ethernet ist die Größe der (Layer-3-)Nutzdaten (wenn man von ''[[Jumbo Frames]]'' absieht) auf 64 (ggf. | [[IP-Paket]]e wiederum sind zwar theoretisch bis 65.535 Bytes (64 [[Kibibyte|KiB]]) spezifiziert, werden aber selbst meist über [[Ethernet]] übertragen, und bei Ethernet ist die Größe der (Layer-3-)Nutzdaten (wenn man von ''[[Jumbo Frames]]'' absieht) auf 64 (ggf. inklusive Padding) bis 1500 Bytes festgelegt. | ||
* TCP- und IP-Protokoll definieren jeweils einen Header von 20 Bytes Größe. | |||
* TCP- und IP-Protokoll definieren jeweils einen Header von 20 Bytes Größe. | * Für die (Applikations-)Nutzdaten bleiben in einem TCP/IP-Paket also 1460 Bytes (= 1500 Bytes Ethernet-[Nutzdaten] − 20 Bytes Headerdaten TCP − 20 Bytes Headerdaten IP) übrig. | ||
* Für die (Applikations-)Nutzdaten bleiben in einem TCP/IP-Paket also 1460 Bytes (= 1500 Bytes Ethernet-[Nutzdaten] − 20 Bytes Headerdaten TCP − 20 Bytes Headerdaten IP) übrig. | * Da die meisten Internet-Anschlüsse [[Digital Subscriber Line|DSL]] verwenden, kommt dort zusätzlich noch das [[Point-to-Point Protocol|Point-to-Point Protocol (PPP)]] zwischen IP und Ethernet zur Anwendung, was weitere 8 Bytes für den PPP-Rahmen verbraucht. | ||
* Da die meisten Internet-Anschlüsse [[Digital Subscriber Line|DSL]] verwenden, kommt dort zusätzlich noch das [[Point-to-Point Protocol|Point-to-Point Protocol (PPP)]] zwischen IP und Ethernet zur Anwendung, was weitere 8 Bytes für den PPP-Rahmen verbraucht. | * Die Nutzdaten reduzieren sich also auf insgesamt 1500 − 20 − 20 − 8 = 1452 Bytes [[Maximum Segment Size|MSS]] (Maximum Segment Size). | ||
* Die Nutzdaten reduzieren sich also auf insgesamt 1500 − 20 − 20 − 8 = 1452 Bytes [[Maximum Segment Size|MSS]] (Maximum Segment Size). | |||
* Dies entspricht einer maximalen Nutzdatenrate von 96,8 %. | * Dies entspricht einer maximalen Nutzdatenrate von 96,8 %. | ||
== Aufteilen der Anwendungsdaten auf TCP-/IP-Segmente == | == Aufteilen der Anwendungsdaten auf TCP-/IP-Segmente == | ||
; Empfänger und Sender einigen sich vor dem Datenaustausch über das Options-Feld auf die Größe der [[Maximum Segment Size|MSS]]. | ; Empfänger und Sender einigen sich vor dem Datenaustausch über das Options-Feld auf die Größe der [[Maximum Segment Size|MSS]]. | ||
* Die Anwendung, die Daten versenden möchte, etwa ein Webserver, legt zum Beispiel einen 7 Kilobyte großen Datenblock im Puffer ab. | * Die Anwendung, die Daten versenden möchte, etwa ein Webserver, legt zum Beispiel einen 7 Kilobyte großen Datenblock im Puffer ab. | ||
; Um mit einem 1460 Byte großen Nutzdatenfeld 7 Kilobyte Daten zu versenden, teilt die TCP-Software die Daten auf mehrere Pakete auf, fügt einen TCP-Header hinzu und versendet die TCP-Segmente. | ; Um mit einem 1460 Byte großen Nutzdatenfeld 7 Kilobyte Daten zu versenden, teilt die TCP-Software die Daten auf mehrere Pakete auf, fügt einen TCP-Header hinzu und versendet die TCP-Segmente. | ||
* Dieser Vorgang wird Segmentierung genannt. | * Dieser Vorgang wird Segmentierung genannt. | ||
* Der Datenblock im Puffer wird in fünf Segmente aufgeteilt (siehe Abb. 6). | * Der Datenblock im Puffer wird in fünf Segmente aufgeteilt (siehe Abb. 6). | ||
* Jedes Segment erhält durch die TCP-Software einen TCP-Header. | * Jedes Segment erhält durch die TCP-Software einen TCP-Header. | ||
* Die TCP-Segmente werden nacheinander abgeschickt. | * Die TCP-Segmente werden nacheinander abgeschickt. | ||
* Diese kommen beim Empfänger nicht notwendigerweise in derselben Reihenfolge an, in der sie versendet wurden, da im Internet unter Umständen jedes TCP-Segment einen anderen Weg nimmt. | * Diese kommen beim Empfänger nicht notwendigerweise in derselben Reihenfolge an, in der sie versendet wurden, da im Internet unter Umständen jedes TCP-Segment einen anderen Weg nimmt. | ||
* Damit die TCP-Software im Empfänger die Segmente wieder sortieren kann, ist jedes Segment nummeriert. | * Damit die TCP-Software im Empfänger die Segmente wieder sortieren kann, ist jedes Segment nummeriert. | ||
* Bei der Zuordnung der Segmente im Empfänger wird die Sequenznummer herangezogen. | * Bei der Zuordnung der Segmente im Empfänger wird die Sequenznummer herangezogen. | ||
[[Datei:Tcp transfer.png|mini|400px| Beispiel eines Datentransfers]] | [[Datei:Tcp transfer.png|mini|400px| Beispiel eines Datentransfers]] | ||
; Die TCP-Software des Empfängers bestätigt diejenigen TCP-Segmente, die einwandfrei (das heißt mit korrekter Prüfsumme) angekommen sind. | ; Die TCP-Software des Empfängers bestätigt diejenigen TCP-Segmente, die einwandfrei (das heißt mit korrekter Prüfsumme) angekommen sind. | ||
* Andernfalls werden die Pakete neu angefordert. | * Andernfalls werden die Pakete neu angefordert. | ||
== Beispiel einer TCP-/IP-Datenübertragung == | == Beispiel einer TCP-/IP-Datenübertragung == | ||
Der Sender schickt sein erstes TCP-Segment mit einer Sequenznummer SEQ=1 (variiert) und einer Nutzdatenlänge von 1460 Bytes an den Empfänger. | ; Der Sender schickt sein erstes TCP-Segment mit einer Sequenznummer SEQ=1 (variiert) und einer Nutzdatenlänge von 1460 Bytes an den Empfänger. | ||
* Der Empfänger bestätigt es mit einem TCP-Header ohne Daten mit ACK=1461 und fordert damit das zweite TCP-Segment ab dem Byte Nummer 1461 beim Sender an. | * Der Empfänger bestätigt es mit einem TCP-Header ohne Daten mit ACK=1461 und fordert damit das zweite TCP-Segment ab dem Byte Nummer 1461 beim Sender an. | ||
* Dieser schickt es dann mit einem TCP-Segment und SEQ=1461 an den Empfänger. | * Dieser schickt es dann mit einem TCP-Segment und SEQ=1461 an den Empfänger. | ||
* Dieser bestätigt es wieder mit einem ACK=2921 und so weiter. | * Dieser bestätigt es wieder mit einem ACK=2921 und so weiter. | ||
* Der Empfänger braucht nicht jedes TCP-Segment zu bestätigen, wenn diese zusammenhängend sind. | * Der Empfänger braucht nicht jedes TCP-Segment zu bestätigen, wenn diese zusammenhängend sind. | ||
* Empfängt er die TCP-Segmente 1–5, so braucht er nur das letzte TCP-Segment zu bestätigen. | * Empfängt er die TCP-Segmente 1–5, so braucht er nur das letzte TCP-Segment zu bestätigen. | ||
* Fehlt zum Beispiel das TCP-Segment 3, weil es verlorengegangen ist, so kann er nur die 1 und die 2 bestätigen, 4 und 5 jedoch noch nicht. | * Fehlt zum Beispiel das TCP-Segment 3, weil es verlorengegangen ist, so kann er nur die 1 und die 2 bestätigen, 4 und 5 jedoch noch nicht. | ||
* Da der Sender keine Bestätigung für die 3 bekommt, läuft sein Timer ab, und er verschickt die 3 noch einmal. | * Da der Sender keine Bestätigung für die 3 bekommt, läuft sein Timer ab, und er verschickt die 3 noch einmal. | ||
* Kommt die 3 beim Empfänger an, so bestätigt er alle fünf TCP-Segmente, sofern beide Seiten die TCP-Option SACK (Selective ACK) unterstützen. | * Kommt die 3 beim Empfänger an, so bestätigt er alle fünf TCP-Segmente, sofern beide Seiten die TCP-Option SACK (Selective ACK) unterstützen. | ||
* Der Sender startet für jedes TCP-Segment, welches er auf die Reise schickt, einen Retransmission Timer. | * Der Sender startet für jedes TCP-Segment, welches er auf die Reise schickt, einen Retransmission Timer. | ||
== Retransmission Timer == | == Retransmission Timer == | ||
Zur Feststellung, wann ein Paket im Netzwerk verloren gegangen ist, wird vom Sender ein [[Timeout (Netzwerktechnik)|Timeout]] verwendet, bis zu dem das ACK der Gegenseite eingetroffen sein muss. | ; Zur Feststellung, wann ein Paket im Netzwerk verloren gegangen ist, wird vom Sender ein [[Timeout (Netzwerktechnik)|Timeout]] verwendet, bis zu dem das ACK der Gegenseite eingetroffen sein muss. | ||
* Ein zu niedriger Timeout bewirkt, dass Pakete, die eigentlich korrekt angekommen sind, wiederholt werden; ein zu hoher Timeout bewirkt, dass bei tatsächlichen Verlusten das zu wiederholende Paket unnötig spät gesendet wird. | * Ein zu niedriger Timeout bewirkt, dass Pakete, die eigentlich korrekt angekommen sind, wiederholt werden; ein zu hoher Timeout bewirkt, dass bei tatsächlichen Verlusten das zu wiederholende Paket unnötig spät gesendet wird. | ||
Aufgrund unterschiedlicher Laufzeiten der zugrundeliegenden IP-Pakete ist nur ein dynamisch an die Verbindung angepasster Timer sinnvoll. | |||
; Aufgrund unterschiedlicher Laufzeiten der zugrundeliegenden IP-Pakete ist nur ein dynamisch an die Verbindung angepasster Timer sinnvoll. | |||
* Die Details werden in RFC 6298<ref>[https://tools.ietf.org/html/rfc6298 RFC 6298 - Computing TCP's Retransmission Timer]</ref> wie folgt festgelegt: | * Die Details werden in RFC 6298<ref>[https://tools.ietf.org/html/rfc6298 RFC 6298 - Computing TCP's Retransmission Timer]</ref> wie folgt festgelegt: | ||
* Der Timeout (RTO = Retransmission Timeout) berechnet sich aus zwei beim Sender mitgeführten Statusvariablen: | * Der Timeout (RTO = Retransmission Timeout) berechnet sich aus zwei beim Sender mitgeführten Statusvariablen: | ||
Zeile 64: | Zeile 64: | ||
Durch die Wahl von 2er-Potenzen (4 bzw. 1/2, 1/4 etc.) als Faktoren, können die Berechnungen in der Implementierung durch einfache [[Bitweiser Operator#Bitweise Verschiebungen|Shift-Operationen]] realisiert werden. | Durch die Wahl von 2er-Potenzen (4 bzw. 1/2, 1/4 etc.) als Faktoren, können die Berechnungen in der Implementierung durch einfache [[Bitweiser Operator#Bitweise Verschiebungen|Shift-Operationen]] realisiert werden. | ||
Zur Messung der RTT muss der [[Karn-Algorithmus]] von [[Phil Karn]] verwendet werden; d. h., es werden nur diejenigen Pakete zur Messung verwendet, deren Bestätigung eintrifft, ohne dass das Paket zwischendurch erneut gesendet wurde. | Zur Messung der RTT muss der [[Karn-Algorithmus]] von [[Phil Karn]] verwendet werden; d. h., es werden nur diejenigen Pakete zur Messung verwendet, deren Bestätigung eintrifft, ohne dass das Paket zwischendurch erneut gesendet wurde. | ||
* Der Grund dafür ist, dass bei einer erneuten Übertragung nicht klar wäre, welches der wiederholt gesendeten Pakete tatsächlich bestätigt wurde, so dass eine Aussage über die RTT eigentlich nicht möglich ist. | * Der Grund dafür ist, dass bei einer erneuten Übertragung nicht klar wäre, welches der wiederholt gesendeten Pakete tatsächlich bestätigt wurde, so dass eine Aussage über die RTT eigentlich nicht möglich ist. | ||
Wurde ein Paket nicht innerhalb des Timeouts bestätigt, so wird der RTO verdoppelt (sofern er noch nicht die optionale obere Schranke erreicht hat). | Wurde ein Paket nicht innerhalb des Timeouts bestätigt, so wird der RTO verdoppelt (sofern er noch nicht die optionale obere Schranke erreicht hat). | ||
* In diesem Fall dürfen (ebenfalls optional) die für SRTT und RTTVAR gefundenen Werte auf ihren Anfangswert zurückgesetzt werden, da sie möglicherweise die Neuberechnung der RTO stören könnten. | * In diesem Fall dürfen (ebenfalls optional) die für SRTT und RTTVAR gefundenen Werte auf ihren Anfangswert zurückgesetzt werden, da sie möglicherweise die Neuberechnung der RTO stören könnten. | ||
== Flusssteuerung und Staukontrolle == | == Flusssteuerung und Staukontrolle == | ||
In den folgenden zwei Abschnitten werden die TCP-Konzepte zur Flusssteuerung und Staukontrolle (oder Überlaststeuerung) erläutert. | In den folgenden zwei Abschnitten werden die TCP-Konzepte zur Flusssteuerung und Staukontrolle (oder Überlaststeuerung) erläutert. | ||
* Dabei werden das ''[[Sliding Window]]'' und das ''[[Congestion Window]]'' eingeführt. | * Dabei werden das ''[[Sliding Window]]'' und das ''[[Congestion Window]]'' eingeführt. | ||
* Der Sender wählt als tatsächliche Sendefenstergröße das Minimum aus beiden Fenstern. | * Der Sender wählt als tatsächliche Sendefenstergröße das Minimum aus beiden Fenstern. | ||
* Um eine zuverlässige Datenübertragung durch Sendewiederholungen zu gewährleisten, werden sogenannte ''[[ARQ-Protokoll]]e'' (englisch Automatic Repeat reQuest, dt. Automatische Wiederholungsanfrage) eingesetzt. | * Um eine zuverlässige Datenübertragung durch Sendewiederholungen zu gewährleisten, werden sogenannte ''[[ARQ-Protokoll]]e'' (englisch Automatic Repeat reQuest, dt. Automatische Wiederholungsanfrage) eingesetzt. | ||
== Flusssteuerung == | == Flusssteuerung == | ||
[[Datei:Sliding window.svg|mini|300px| Sliding Window]] | [[Datei:Sliding window.svg|mini|300px| Sliding Window]] | ||
; Da die Anwendung Daten aus dem Puffer liest, ändert sich der Füllstand des Puffers ständig. | ; Da die Anwendung Daten aus dem Puffer liest, ändert sich der Füllstand des Puffers ständig. | ||
* Deshalb ist es notwendig, den Datenfluss dem Füllstand entsprechend zu steuern. | * Deshalb ist es notwendig, den Datenfluss dem Füllstand entsprechend zu steuern. | ||
* Dies geschieht mit dem ''[[Sliding Window]]'' und dessen Größe. | * Dies geschieht mit dem ''[[Sliding Window]]'' und dessen Größe. | ||
Den Puffer des Senders erweitern wir, wie in | |||
* In der | ; Den Puffer des Senders erweitern wir, wie in der Abbildung zu sehen, auf 10 Segmente | ||
* Die Übertragung ist vergleichbar mit | * In der Abbildung werden gerade die Segmente 1–5 übertragen. | ||
* Obwohl der Puffer des Empfängers | * Die Übertragung ist vergleichbar mit der Abbildung oben | ||
* Dies hat zur Folge, dass das nächste TCP-Segment vom Empfänger nicht mehr verarbeitet werden kann. | * Obwohl der Puffer des Empfängers am Ende voll ist, fordert er mit ACK=7301 die nächsten Daten ab dem Byte 7301 beim Sender an. | ||
* Ausnahmen sind jedoch TCP-Segmente mit gesetztem URG-Flag. | * Dies hat zur Folge, dass das nächste TCP-Segment vom Empfänger nicht mehr verarbeitet werden kann. | ||
* Mit dem [[RWin|Window]]-Feld kann er dem Sender mitteilen, dass er keine Daten mehr verschicken soll. | * Ausnahmen sind jedoch TCP-Segmente mit gesetztem URG-Flag. | ||
* Dies geschieht, indem er im Window-Feld den Wert Null einträgt (Zero Window). | * Mit dem [[RWin|Window]]-Feld kann er dem Sender mitteilen, dass er keine Daten mehr verschicken soll. | ||
* Der Wert Null entspricht dem freien Speicherplatz im Puffer. | * Dies geschieht, indem er im Window-Feld den Wert Null einträgt (Zero Window). | ||
* Die Anwendung des Empfängers liest nun die Segmente 1–5 aus dem Puffer, womit wieder ein Speicherplatz von 7300 Byte frei ist. | * Der Wert Null entspricht dem freien Speicherplatz im Puffer. | ||
* Damit kann er die restlichen Segmente 6–10 mit einem TCP-Header, der die Werte SEQ=1, ACK=7301 und Window=7300 enthält, beim Sender anfordern. | * Die Anwendung des Empfängers liest nun die Segmente 1–5 aus dem Puffer, womit wieder ein Speicherplatz von 7300 Byte frei ist. | ||
* Der Sender weiß nun, dass er maximal fünf TCP-Segmente an den Empfänger schicken kann, und verschiebt das Window um fünf Segmente nach rechts (siehe Abb. 8b). | * Damit kann er die restlichen Segmente 6–10 mit einem TCP-Header, der die Werte SEQ=1, ACK=7301 und Window=7300 enthält, beim Sender anfordern. | ||
* Die Segmente 6–10 werden nun alle zusammen als ''Burst'' verschickt. | * Der Sender weiß nun, dass er maximal fünf TCP-Segmente an den Empfänger schicken kann, und verschiebt das Window um fünf Segmente nach rechts (siehe Abb. 8b). | ||
* Die Segmente 6–10 werden nun alle zusammen als ''Burst'' verschickt. | |||
* Kommen alle TCP-Segmente beim Empfänger an, so quittiert er sie mit SEQ=1 und ACK=14601 und fordert die nächsten Daten an. | * Kommen alle TCP-Segmente beim Empfänger an, so quittiert er sie mit SEQ=1 und ACK=14601 und fordert die nächsten Daten an. | ||
; Silly Window Syndrome | ; Silly Window Syndrome | ||
: Der Empfänger sendet ein ''Zero Window'' an den Sender, da sein Puffer voll ist. | : Der Empfänger sendet ein ''Zero Window'' an den Sender, da sein Puffer voll ist. | ||
* Die Anwendung beim Empfänger liest allerdings nur zwei Byte aus dem Puffer. | * Die Anwendung beim Empfänger liest allerdings nur zwei Byte aus dem Puffer. | ||
* Der Empfänger schickt einen TCP-Header mit Window=2 (Window Update) an den Sender und fordert gleichzeitig die zwei Byte an. | * Der Empfänger schickt einen TCP-Header mit Window=2 (Window Update) an den Sender und fordert gleichzeitig die zwei Byte an. | ||
* Der Sender kommt der Aufforderung nach und schickt die zwei Byte in einem 42 Byte großen Paket (mit IP-Header und TCP-Header) an den Empfänger. | * Der Sender kommt der Aufforderung nach und schickt die zwei Byte in einem 42 Byte großen Paket (mit IP-Header und TCP-Header) an den Empfänger. | ||
* Damit ist der Puffer des Empfängers wieder voll, und er schickt wieder ein ''Zero Window'' an den Sender. | * Damit ist der Puffer des Empfängers wieder voll, und er schickt wieder ein ''Zero Window'' an den Sender. | ||
* Die Anwendung liest jetzt zum Beispiel hundert Byte aus dem Puffer. | * Die Anwendung liest jetzt zum Beispiel hundert Byte aus dem Puffer. | ||
* Der Empfänger schickt wieder einen TCP-Header mit einem kleinen Window-Wert an den Sender. | * Der Empfänger schickt wieder einen TCP-Header mit einem kleinen Window-Wert an den Sender. | ||
* Dieses Spiel setzt sich immer wieder fort und verschwendet Bandbreite, da nur sehr kleine Pakete versandt werden. | * Dieses Spiel setzt sich immer wieder fort und verschwendet Bandbreite, da nur sehr kleine Pakete versandt werden. | ||
* Clarks Lösung ist, dass der Empfänger ein ''Zero Window'' sendet und so lange mit dem ''Window Update'' warten soll, bis die Anwendung mindestens die maximale Segmentgröße (maximum segment size, in unseren bisherigen Beispielen 1460 Byte) aus dem Puffer gelesen hat oder der Puffer halbleer ist – je nachdem, was zuerst eintritt (Dave Clark, 1982). | * Clarks Lösung ist, dass der Empfänger ein ''Zero Window'' sendet und so lange mit dem ''Window Update'' warten soll, bis die Anwendung mindestens die maximale Segmentgröße (maximum segment size, in unseren bisherigen Beispielen 1460 Byte) aus dem Puffer gelesen hat oder der Puffer halbleer ist – je nachdem, was zuerst eintritt (Dave Clark, 1982). | ||
* Auch der Sender kann zu kleine Pakete abschicken und dadurch Bandbreite verschwenden. | * Auch der Sender kann zu kleine Pakete abschicken und dadurch Bandbreite verschwenden. | ||
* Dieser Umstand wird mit dem [[Nagle-Algorithmus]] beseitigt. | * Dieser Umstand wird mit dem [[Nagle-Algorithmus]] beseitigt. | ||
* Deswegen ergänzt er sich mit Clarks Lösung. | * Deswegen ergänzt er sich mit Clarks Lösung. | ||
== Überlaststeuerung/Staukontrolle (Congestion Control) == | == Überlaststeuerung/Staukontrolle (Congestion Control) == | ||
[[Transmission Control Protocol/Überlastungskontrolle]] | |||
== Siehe auch == | == Siehe auch == | ||
=== Dokumentation === | === Dokumentation === | ||
==== RFC ==== | ==== RFC ==== | ||
==== Man- | ==== Man-Page ==== | ||
==== Info-Pages ==== | ==== Info-Pages ==== | ||
=== Links === | === Links === | ||
==== Projekt ==== | ==== Projekt ==== | ||
==== Weblinks ==== | ==== Weblinks ==== | ||
[[Kategorie: | [[Kategorie:TCP]] |
Aktuelle Version vom 6. November 2024, 12:49 Uhr
topic - Kurzbeschreibung
Beschreibung
TCP-/IP-Segment-Größe
- Ein TCP-Segment hat typischerweise eine Größe von maximal 1500 Bytes.
- Ein TCP-Segment muss jedoch in die darunter liegende Übertragungsschicht passen, das Internetprotokoll (IP); siehe hierzu auch Maximum Transmission Unit (MTU).
IP-Pakete wiederum sind zwar theoretisch bis 65.535 Bytes (64 KiB) spezifiziert, werden aber selbst meist über Ethernet übertragen, und bei Ethernet ist die Größe der (Layer-3-)Nutzdaten (wenn man von Jumbo Frames absieht) auf 64 (ggf. inklusive Padding) bis 1500 Bytes festgelegt.
- TCP- und IP-Protokoll definieren jeweils einen Header von 20 Bytes Größe.
- Für die (Applikations-)Nutzdaten bleiben in einem TCP/IP-Paket also 1460 Bytes (= 1500 Bytes Ethernet-[Nutzdaten] − 20 Bytes Headerdaten TCP − 20 Bytes Headerdaten IP) übrig.
- Da die meisten Internet-Anschlüsse DSL verwenden, kommt dort zusätzlich noch das Point-to-Point Protocol (PPP) zwischen IP und Ethernet zur Anwendung, was weitere 8 Bytes für den PPP-Rahmen verbraucht.
- Die Nutzdaten reduzieren sich also auf insgesamt 1500 − 20 − 20 − 8 = 1452 Bytes MSS (Maximum Segment Size).
- Dies entspricht einer maximalen Nutzdatenrate von 96,8 %.
Aufteilen der Anwendungsdaten auf TCP-/IP-Segmente
- Empfänger und Sender einigen sich vor dem Datenaustausch über das Options-Feld auf die Größe der MSS.
- Die Anwendung, die Daten versenden möchte, etwa ein Webserver, legt zum Beispiel einen 7 Kilobyte großen Datenblock im Puffer ab.
- Um mit einem 1460 Byte großen Nutzdatenfeld 7 Kilobyte Daten zu versenden, teilt die TCP-Software die Daten auf mehrere Pakete auf, fügt einen TCP-Header hinzu und versendet die TCP-Segmente.
- Dieser Vorgang wird Segmentierung genannt.
- Der Datenblock im Puffer wird in fünf Segmente aufgeteilt (siehe Abb. 6).
- Jedes Segment erhält durch die TCP-Software einen TCP-Header.
- Die TCP-Segmente werden nacheinander abgeschickt.
- Diese kommen beim Empfänger nicht notwendigerweise in derselben Reihenfolge an, in der sie versendet wurden, da im Internet unter Umständen jedes TCP-Segment einen anderen Weg nimmt.
- Damit die TCP-Software im Empfänger die Segmente wieder sortieren kann, ist jedes Segment nummeriert.
- Bei der Zuordnung der Segmente im Empfänger wird die Sequenznummer herangezogen.
- Die TCP-Software des Empfängers bestätigt diejenigen TCP-Segmente, die einwandfrei (das heißt mit korrekter Prüfsumme) angekommen sind.
- Andernfalls werden die Pakete neu angefordert.
Beispiel einer TCP-/IP-Datenübertragung
- Der Sender schickt sein erstes TCP-Segment mit einer Sequenznummer SEQ=1 (variiert) und einer Nutzdatenlänge von 1460 Bytes an den Empfänger.
- Der Empfänger bestätigt es mit einem TCP-Header ohne Daten mit ACK=1461 und fordert damit das zweite TCP-Segment ab dem Byte Nummer 1461 beim Sender an.
- Dieser schickt es dann mit einem TCP-Segment und SEQ=1461 an den Empfänger.
- Dieser bestätigt es wieder mit einem ACK=2921 und so weiter.
- Der Empfänger braucht nicht jedes TCP-Segment zu bestätigen, wenn diese zusammenhängend sind.
- Empfängt er die TCP-Segmente 1–5, so braucht er nur das letzte TCP-Segment zu bestätigen.
- Fehlt zum Beispiel das TCP-Segment 3, weil es verlorengegangen ist, so kann er nur die 1 und die 2 bestätigen, 4 und 5 jedoch noch nicht.
- Da der Sender keine Bestätigung für die 3 bekommt, läuft sein Timer ab, und er verschickt die 3 noch einmal.
- Kommt die 3 beim Empfänger an, so bestätigt er alle fünf TCP-Segmente, sofern beide Seiten die TCP-Option SACK (Selective ACK) unterstützen.
- Der Sender startet für jedes TCP-Segment, welches er auf die Reise schickt, einen Retransmission Timer.
Retransmission Timer
- Zur Feststellung, wann ein Paket im Netzwerk verloren gegangen ist, wird vom Sender ein Timeout verwendet, bis zu dem das ACK der Gegenseite eingetroffen sein muss.
- Ein zu niedriger Timeout bewirkt, dass Pakete, die eigentlich korrekt angekommen sind, wiederholt werden; ein zu hoher Timeout bewirkt, dass bei tatsächlichen Verlusten das zu wiederholende Paket unnötig spät gesendet wird.
- Aufgrund unterschiedlicher Laufzeiten der zugrundeliegenden IP-Pakete ist nur ein dynamisch an die Verbindung angepasster Timer sinnvoll.
- Die Details werden in RFC 6298[1] wie folgt festgelegt:
- Der Timeout (RTO = Retransmission Timeout) berechnet sich aus zwei beim Sender mitgeführten Statusvariablen:
- der geschätzten Round Trip Time (SRTT = Smoothed RTT)
- sowie deren Varianz (RTTVAR).
- Initial wird geschätzt, dass RTO = 1s (um die Kompatibilität mit der älteren Version des Dokuments zu schaffen sind auch Werte > 1s möglich.)
- Nach der Messung der RTT des ersten gesendeten Pakets wird gesetzt:
- SRTT:= RTT
- RTTVAR:= 0,5 * RTT
- RTO:= RTT + 4 * RTTVAR (Sollte 4 * RTTVAR kleiner sein als die Messgenauigkeit des Timers, wird stattdessen diese addiert.)
- Bei jeder weiteren Messung der RTT' werden die Werte aktualisiert (hierbei muss RTTVAR vor SRTT berechnet werden):
- RTTVAR:= (1-β) * RTTVAR + β * |SRTT – RTT'| (Auch die Varianz wird mit einem Faktor β geglättet; da die Varianz eine durchschnittliche Abweichung angibt (welche immer positiv ist), wird hier der Betrag der Abweichung von geschätzter und tatsächlicher RTT' verwendet, nicht die einfache Differenz. Es wird empfohlen, β = 1/4 zu wählen.)
- SRTT:= (1-α) * SRTT + α * RTT' (Es wird somit nicht einfach die neue RTT' gesetzt, sondern diese mit einem Faktor α geglättet. Es wird empfohlen, α = 1/8 zu wählen.)
- RTO:= SRTT + 4 * RTTVAR (Sollte 4*RTTVAR kleiner sein als die Messgenauigkeit des Timers, wird stattdessen diese addiert. Für den RTO gilt – unabhängig von der Berechnung – ein Minimalwert von 1 s; es darf auch ein Maximalwert vergeben werden, sofern dieser mindestens 60 s beträgt.)
Durch die Wahl von 2er-Potenzen (4 bzw. 1/2, 1/4 etc.) als Faktoren, können die Berechnungen in der Implementierung durch einfache Shift-Operationen realisiert werden.
Zur Messung der RTT muss der Karn-Algorithmus von Phil Karn verwendet werden; d. h., es werden nur diejenigen Pakete zur Messung verwendet, deren Bestätigung eintrifft, ohne dass das Paket zwischendurch erneut gesendet wurde.
- Der Grund dafür ist, dass bei einer erneuten Übertragung nicht klar wäre, welches der wiederholt gesendeten Pakete tatsächlich bestätigt wurde, so dass eine Aussage über die RTT eigentlich nicht möglich ist.
Wurde ein Paket nicht innerhalb des Timeouts bestätigt, so wird der RTO verdoppelt (sofern er noch nicht die optionale obere Schranke erreicht hat).
- In diesem Fall dürfen (ebenfalls optional) die für SRTT und RTTVAR gefundenen Werte auf ihren Anfangswert zurückgesetzt werden, da sie möglicherweise die Neuberechnung der RTO stören könnten.
Flusssteuerung und Staukontrolle
In den folgenden zwei Abschnitten werden die TCP-Konzepte zur Flusssteuerung und Staukontrolle (oder Überlaststeuerung) erläutert.
- Dabei werden das Sliding Window und das Congestion Window eingeführt.
- Der Sender wählt als tatsächliche Sendefenstergröße das Minimum aus beiden Fenstern.
- Um eine zuverlässige Datenübertragung durch Sendewiederholungen zu gewährleisten, werden sogenannte ARQ-Protokolle (englisch Automatic Repeat reQuest, dt. Automatische Wiederholungsanfrage) eingesetzt.
Flusssteuerung
- Da die Anwendung Daten aus dem Puffer liest, ändert sich der Füllstand des Puffers ständig.
- Deshalb ist es notwendig, den Datenfluss dem Füllstand entsprechend zu steuern.
- Dies geschieht mit dem Sliding Window und dessen Größe.
- Den Puffer des Senders erweitern wir, wie in der Abbildung zu sehen, auf 10 Segmente
- In der Abbildung werden gerade die Segmente 1–5 übertragen.
- Die Übertragung ist vergleichbar mit der Abbildung oben
- Obwohl der Puffer des Empfängers am Ende voll ist, fordert er mit ACK=7301 die nächsten Daten ab dem Byte 7301 beim Sender an.
- Dies hat zur Folge, dass das nächste TCP-Segment vom Empfänger nicht mehr verarbeitet werden kann.
- Ausnahmen sind jedoch TCP-Segmente mit gesetztem URG-Flag.
- Mit dem Window-Feld kann er dem Sender mitteilen, dass er keine Daten mehr verschicken soll.
- Dies geschieht, indem er im Window-Feld den Wert Null einträgt (Zero Window).
- Der Wert Null entspricht dem freien Speicherplatz im Puffer.
- Die Anwendung des Empfängers liest nun die Segmente 1–5 aus dem Puffer, womit wieder ein Speicherplatz von 7300 Byte frei ist.
- Damit kann er die restlichen Segmente 6–10 mit einem TCP-Header, der die Werte SEQ=1, ACK=7301 und Window=7300 enthält, beim Sender anfordern.
- Der Sender weiß nun, dass er maximal fünf TCP-Segmente an den Empfänger schicken kann, und verschiebt das Window um fünf Segmente nach rechts (siehe Abb. 8b).
- Die Segmente 6–10 werden nun alle zusammen als Burst verschickt.
- Kommen alle TCP-Segmente beim Empfänger an, so quittiert er sie mit SEQ=1 und ACK=14601 und fordert die nächsten Daten an.
- Silly Window Syndrome
- Der Empfänger sendet ein Zero Window an den Sender, da sein Puffer voll ist.
- Die Anwendung beim Empfänger liest allerdings nur zwei Byte aus dem Puffer.
- Der Empfänger schickt einen TCP-Header mit Window=2 (Window Update) an den Sender und fordert gleichzeitig die zwei Byte an.
- Der Sender kommt der Aufforderung nach und schickt die zwei Byte in einem 42 Byte großen Paket (mit IP-Header und TCP-Header) an den Empfänger.
- Damit ist der Puffer des Empfängers wieder voll, und er schickt wieder ein Zero Window an den Sender.
- Die Anwendung liest jetzt zum Beispiel hundert Byte aus dem Puffer.
- Der Empfänger schickt wieder einen TCP-Header mit einem kleinen Window-Wert an den Sender.
- Dieses Spiel setzt sich immer wieder fort und verschwendet Bandbreite, da nur sehr kleine Pakete versandt werden.
- Clarks Lösung ist, dass der Empfänger ein Zero Window sendet und so lange mit dem Window Update warten soll, bis die Anwendung mindestens die maximale Segmentgröße (maximum segment size, in unseren bisherigen Beispielen 1460 Byte) aus dem Puffer gelesen hat oder der Puffer halbleer ist – je nachdem, was zuerst eintritt (Dave Clark, 1982).
- Auch der Sender kann zu kleine Pakete abschicken und dadurch Bandbreite verschwenden.
- Dieser Umstand wird mit dem Nagle-Algorithmus beseitigt.
- Deswegen ergänzt er sich mit Clarks Lösung.
Überlaststeuerung/Staukontrolle (Congestion Control)
Transmission Control Protocol/Überlastungskontrolle