IT-Academy Logo
Sign Up Login Help
Home - Netzwerke - Protokolle - Transmission Control Protocol (TCP)



Transmission Control Protocol (TCP)

Ohne TCP wäre es sehr schwierig in Netzwerken fehlerfreie Verbindundungen aufzubauen. TCP sorgt dafür, dass Daten verlässlich und sicher am jeweiligen Rechner eintreffen.


Autor: Martin Puaschitz (onestone)
Datum: 23-01-2002, 19:06:04
Referenzen: Hall, Eric. A - Internet Core Protocols; O'Reily 2000
Schwierigkeit: Fortgeschrittene
Ansichten: 8058x
Rating: 4.67 (3x bewertet)

Hinweis:

Für den hier dargestellte Inhalt ist nicht der Betreiber der Plattform, sondern der jeweilige Autor verantwortlich.
Falls Sie Missbrauch vermuten, bitten wir Sie, uns unter missbrauch@it-academy.cc zu kontaktieren.

[Druckansicht] [Als E-Mail senden] [Kommentar verfassen]



Fachbereichsarbeit

1. Einleitung

Nun folgt das wichtigste Protokoll innerhalb von Netzwerken: TCP. Es ist neben UDP eines der beiden häufigsten Kommunikationsprotokolle, die heutzutage verwendet werden. Der Unterschied ist, dass UDP eine schnelle, aber unsichere Übertragung ermöglicht, hingegen TCP-Verbindungen sehr ausfallsicher und kontrollierter sind. Die meisten Anwendungen verwenden in der heutigen Zeit TCP, da es die beste Variante darstellt um Daten sicher und ohne Probleme zu übertragen.

Die erste Version von TCP wurde sogar vor IP geschrieben. Später erkannte man allerdings, dass es sinnvoller wäre, IP aus dem TCP-Protokoll herauszunehmen und als separates Protokoll arbeiten zu lassen. Somit wurden die Aufgaben verteilt, und jedes Protokoll konzentrierte sich auf das, was es am besten konnte. Deshalb findet sich der Begriff TCP/IP heute relativ oft in der Computerwelt. Diese beiden Protokolle arbeiten sehr verflochten miteinander und sind extrem weit verbreitet.

1.1. Die Spezifikation

TCP ist in RFC 793 erstmalig spezifiziert und mittlerweile als STD 7 erneut veröffentlicht worden – somit zählt auch TCP zu den Internet Standard Protokollen. Die Protocol ID von TCP ist 6. Sobald ein System ein IP-Paket mit einer Protocol ID von 6 empfängt, muss es dieses Paket an das lokale TCP Service weiterleiten.

1.2. TCP ist verlässlich und verbindungsorientiert

Alle Transport-Protokolle verwenden IP für die Übertragung der Daten über die physikalischen Medien. Da aber IP sehr unzuverlässig ist und Pakete einfach verloren gehen können, ist die alleinige Nutzung von IP für viele Programme nicht sinnvoll. Applikationen wie Telnet, E-Mail und ähnliche benötigen eine stabile und vor allem verlässliche Verbindung zwischen zwei Systemen.

Diese Verlässlichkeit kann vor allem TCP bieten. TCP verwaltet eine voll-duplexe Punkt-zu-Punkt Verbindung zwischen zwei Systemen, welche durch eine virtuelle Kreisverbindung aufgebaut wird. Sobald also TCP Daten an ein anderes System senden möchte, wird diese Kreisverbindung zwischen den beiden Systemen aufgebaut. Dadurch ist es möglich, die Verbindung sehr genau zu überwachen; beide Systeme wissen immer was der Andere gerade macht.

Aufgrund dieser virtuellen Kreisverbindung ist TCP auch langsamer als UDP. UDP benötigt nicht einen Aufbau eines solchen Kreises – es schickt die Daten direkt. Das macht UDP auch immer noch ein wenig unsicherer als TCP.

1.3. TCP-Dienste

Eigentlich könnte jede Applikation selbst ihre Verbindung zu anderen System verwalten, verlorengegangene Pakete bemerken, erneut anfordern und so weiter. Doch dies wäre unvorteilhaft. Diese Aufgabe wird einem Protokoll innerhalb des Transport-Layers übergeben. Dadurch profitieren alle Applikationen und die Zusammenarbeit ist erheblich erleichtert.

Nun folgenden die wichtigsten Dienste, die TCP den Applikationen zu Verfügung stellt:

Virtual circuits

Wann auch immer zwei Systeme über TCP Daten austauschen möchten, wird eine virtuelle Kreisverbindung zwischen diesen beiden System aufgebaut. Dies ist das Kernstück einer jeden TCP Verbindung, durch welches Verlässlichkeit, Datenflusskontrolle und I/O Management ermöglicht wird. Dies ist auch der Punkt, welcher TCP von UDP unterscheidet.

Application I/O management

Applikationen kommunizieren miteinander, indem sie die jeweiligen Daten an das lokale TCP-Service weiterreichen, TCP die Daten über die virtuelle Kreisverbindung versendet und das andere TCP-Service diese Daten empfängt. TCP bietet den Applikationen die Möglichkeit, einen Zwischenspeicher auf beiden Seiten zu verwenden, damit die Daten ständig als fortlaufender Strom gesendet werden können.

Network I/O management

Wenn TCP Daten an ein anderes System versenden möchte, wendet es sich – wie alle Transportprotokolle – an IP. TCP bietet auch IP gegenüber ein System an, womit es möglich ist, die sendenden Daten sinnvoll an IP weiterzureichen, damit diese effizient übertragen werden können. Dies nennt man Network I/O management.

Flow control

Nicht alle Systeme in Netzwerken haben die gleichen Vorraussetzungen. Verschiedene Bandbreiten, unterschiedliche Speicherkapazitäten und so weiter. Aus diesem Grund muss TCP eine Möglichkeit besitzen, den Datenstrom dementsprechend immer anzupassen. Wichtig ist, dass TCP dies ohne Einwirken der Applikationen zustande bringt.

Reliability

TCP bietet eine sehr verlässliche Datenübertragung an, da es die Daten, die es sendet, ständig überwacht. Es werden sogenannte sequence-numbers verwendet, um jedes einzelne Byte der Daten zu kennzeichnen, Acknowledgement flags, um zu überprüfen, ob irgendwelche dieser Bytes verlorengegangen sind und Checksums, ob die Daten als gesamtes korrekt sind.

Zusammen ermöglichen diese Dienste TCP ein starkes, sicheres und verlässliches Transportprotokoll darzustellen.

1.4. Virtuelle Kreisverbindung

Da TCP ja eine verlässliche Datenübertragung gewährleisten möchte, muss es die Ungenauigkeit von IP in irgendeiner Form überwachen können. Dies ist über eine virtuelle Kreisverbindung zwischen den zwei Endpunkte der Übertragung möglich. Wenn eine Verbindung zwischen zwei TCP-Systemen aufgebaut wird, werden jegliche Daten über die virtuelle Kreisverbindung gesendet. Die folgende Grafik 3.13 erläutert dieses Schema:

Grafik 3.13

Um TCP ein wenig besser zu verstehen, ist es oft gerne gesehen, es mit einem Telefongespräch zu vergleichen. Sobald eine Applikation Daten mit einem anderen System austauschen möchte, schickt sie eine Anfrage über eine virtuelle Kreisverbindung an das entsprechende System. Dieser Prozess kann mit dem Wählen der Telefonnummer verglichen werden. Sobald der Gesprächspartner sich mit „Hallo?“ meldet, wird bestätigt, dass die Übertragung funktioniert hat. Sobald nun der eigentliche Anrufer sich mit „Hallo, hier ist Martin!“ meldet, ist die Verbindung der beiden Gesprächspartner aufgebaut und es können Daten (in unserem Beispiel Sprache) übertragen werden.

Ähnlich sieht es auch bei der Fehlerkorrektur aus. Wenn ein Gesprächspartner den anderen nicht versteht (warum auch immer) würde er sagen „Entschuldige, was hast du gesagt?“ und der andere würde mit „Ich sagte...“ antworten. Wenn plötzlich die Kommunikation nicht mehr möglich ist, werden beide irgendwann den Hörer auflegen und die Verbindung beenden (um es eventuell später erneut zu versuchen). Falls jedoch alles in Ordnung ist, werden solange Daten übertragen, bis sich die Gesprächspartner verabschieden: „Ok, mach’s gut“ – „Ciao!“. Damit beenden auch beide die Verbindung.

Dieses Konzept ist in Grafik 3.14 erneut dargestellt. Sobald der „Anruf“ durchgekommen ist und das entfernte System dementsprechend antwortet („Hallo?“) und der Anrufer seinen Gesprächspartner auch gegrüßt hat („Hallo, hier ist Martin!“) wurde ein sogenanntes three-way handshake ausgeführt. Nun ist die Verbindung zwischen den System aufrecht und es können Daten übertragen werden.

Grafik 3.14

Man könnte es als Nachteil auffassen, dass wenn immer zwei Geräte via TCP Daten austauschen wollen, immer eine neue virtuelle Kreisverbindung aufgebaut werden muss. Wenn zum Beispiel ein Webbrowser vier verschiedene Bilder von einem WebServer abfragen möchte und dies mehr oder weniger gleichzeitig will, müssen vier unterschiedliche Verbindungen zwischen diesen beiden Systemen aufgebaut werden. Somit kann es also sein, dass ein stark frequentierter Server ständig eine große Anzahl an verschiedenen virtuellen Kreisverbindungen zu verschiedenen Systemen aufrecht erhalten muss.

1.5. Application I/O management

TCP ist für die verschiedenen Applikationen eine sehr große Hilfe. Es übernimmt jeglichen Datentransfer und dessen Überwachung. Dadurch ist es möglich, dass keine Applikation selbst derartige Funktionen implementiert haben muss, was das gesamte System erheblich vereinfacht. TCP ist die zentrale Anlaufstelle für Applikationen, wenn Daten übertragen werden müssen (via TCP!).

Besonders wichtig ist hier das Application I/O management. Dadurch ist es für die einzelnen Anwendungen möglich, ihre Daten in einem kontinuierlichen Strom an TCP zu senden und auch genauso von diesem zu empfangen. Die Programme müssen sich nicht um die Fragmentierung von Datagrammen oder um die Wiederzusammenstellung von Paketen kümmern. Diese Aufgaben werden von TCP, bzw. IP vollständig übernommen.

TCP bietet den Applikationen vier verschiedene Funktionen des Application I/O management Services an, welche nun in den folgenden Kapiteln beschrieben werden.

1.5.1. Interne Adressierung

Wie UDP (siehe Kapitel 3.4.2.) teilt auch TCP den einzelnen Anwendungen verschiedene Portnummern zu. Dadurch ist es TCP möglich, eingehende Daten den jeweiligen Applikationen direkt weiterzuleiten.

1.5.2. Virtuelle Kreisverbindungen öffnen

Applikationen informieren das lokale TCP-Service, sobald sie eine virtuelle Kreisverbindung zu einem anderen System benötigen. TCP übernimmt dann die Arbeit diese Verbindung aufzubauen.

Es gibt zwei verschiedene Möglichkeiten eine solche Verbindung zu öffnen. Die eine ist der sogenannte „active opens“. Hier möchte die Anwendung eine virtuelle Kreisverbindung zu einem anderen System aufbauen – ist also aktiv. Die zweite Möglichkeit ist der passive open. Hier möchte eine Applikation auf eingehende active opens warten (dies kann z.B. ein Webserver sein) – ist also passiv.

Die folgende Grafik 3.15 veranschaulicht die Abfrage einer Internetseite. Der Client verwendet active open um die Verbindung aufzubauen. Da der Server in passive open bereits auf eingehende Verbindungen wartet, kann eine Verbindung aufgebaut werden.

Grafik 3.15

Wichtig anzumerken ist, dass die ersten Pakete, die zwischen den Systemen gesendet werden, durchaus nicht leer sind – sie enthalten wichtige Steuerinformationen. Im ersten Paket, welches vom Client ausgeht ist die Synchronize Flag gesetzt, um dem Server mitzuteilen, dass dies eine neue Verbindungsanfrage darstellt. Nebenbei beinhaltet diese Anfrage auch die sequence number (= das erste Byte), welche der Client verwenden wird, sobald Daten gesendet werden können.

Wenn der Server nun einwilligt eine Verbindung aufzubauen, sendet er ein Segment zurück, welches ebenfalls die Synchronize Flag gesetzt hat (da die Verbindung ja erst aufgebaut wird). Weiters ist das Acknowledgement flag gesetzt und der Acknowledgement Identifier ist auf das nächste zu erwartende Byte des Clients gesetzt.

Dann antwortet der Client mit einem Segment, in welchem wieder die Acknowledge flag gesetzt ist und in welcher der Acknowledgement Identifier auf das nächste zu erwartende Byte des Servers gesetzt ist. In diesem Segment ist die Synchronize Flag nicht mehr gesetzt, da die Verbindung bereits aufgebaut ist.

1.5.3. Daten übertragen

Wann immer eine Applikation Daten übertragen möchte, gibt sie diese Daten an TCP weiter und nimmt an, dass TCP alles tun wird was notwendig ist, damit diese Daten beim Empfänger ankommen.

Sobald TCP eine gewisse Menge an Daten von der Applikation erhalten hat, sendet es diese zum jeweiligen Empfänger. Die Daten werden dann in ein IP-Datagramm gebündelt und via IP versendet. Das IP-Service des Empfängers erhält das Datagramm, bemerkt anhand des Protocol Identifier, dass dies ein TCP-Datagramm ist und gibt es an TCP weiter. TCP kann dann aufgrund der Portnummer feststellen, an welche Applikation die Daten weitergeleitet werden sollen.

In Grafik 3.16 ist dieses Schema erneut verdeutlicht. Wir setzen unser Beispiel von vorhin fort. Nun möchte der Client ein Dokument des Servers abrufen – er sendet die Anfrage zu TCP, von welchem es dann via IP zum Server geschickt wird. Dort wird die Anfrage dementsprechend verarbeitet und die Daten im selben Schema zurückgesendet.

Es ist allerdings wichtig zu beachten, dass jegliche Daten der Applikationen in separaten TCP-Segmenten versendet werden und alle einzeln bestätigt werden müssen (Schritt 7).

Grafik 3.16

1.5.4. Virtuelle Kreisverbindungen schließen

Wenn Applikationen mit ihrer Datenübertragung fertig sind, informieren sie das lokale TCP-Service, welches dann die Verbindung terminiert. Das Schließen eines Verbindung ist sehr ähnlich ihrem Aufbau.

Auch hier gibt es zwei verschiedene Modi, welche angewendet werden. Derjenige, der zur Terminierung der Verbindung aufruft, verwendet active close. Dadurch ist das andere System verpflichtet, mit einem passive close zu antworten. Sobald der Terminierende diese Bestätigung erneut bestätigt hat, wird die Verbindung auf beiden Seiten beendet. Die folgende Grafik 3.17 soll unser bisheriges Beispiel nun abschließen:

Grafik 3.17

Wie bei dem Aufbau einer virtuellen Verbindung, wo Synchronize Flags verwendet werden gibt es beim Abbau einer Verbindung entsprechende Finish Flags. Diese müssen gesetzt werden, um das andere System dementsprechend zu informieren.

Zu bemerken ist allerdings, dass vor allem bei den Servern nur die virtuelle Kreisverbindung geschlossen wird – nicht der Port. Der Port wird erst dann geschlossen, wenn die entsprechende Applikation nicht mehr läuft (z.B. ein Webserver). Fazit: Nachdem der Webserver die Verbindung zu Ferret beendet hat, kann der Webserver dennoch weitere Verbindungen von Fungi annehmen.

1.6. Network I/O Management

Applikationen, die Daten über TCP senden wollen, müssen die Daten an TCP übergeben. TCP wartet ein wenig ab, bis genügend Daten zusammengekommen sind, um diese dann gebündelt als ein sogenanntes Segment zu übertragen. Um ein Netzwerk optimal auszulasten, ist die Größe dieser Segmente sehr wichtig.

Jedes TCP-Segment hat immer einen Header von 40 Byte (20 von IP, 20 von TCP). Wenn wir als Beispiel genau ein Byte an Daten übertragen, hätten wir ein Verhältnis von 41:1 – eine sehr miserable Auslastung. Optimal ist es, wenn die Datenmenge vier Kilobyte beträgt, denn dann ist das Verhältnis 1:101.

Es ist also leicht zu erkennen, dass es unvorteilhaft sein kann, zu wenig Daten in ein TCP Segment zu packen, da dann mehr Header-Informationen als Daten übertragen werden. Doch es ist genauso schlecht für die Übertragungsgeschwindigkeit wenn es zu viele Daten sind. Sobald Sie mehr Daten in ein Segment packen, als die MTU der physischen Leiter zulässt, müssen die Segmente fragmentiert werden. Das wiederum kostet Zeit und Mühe.

Um die richtige Segmentgröße festzustellen, bedarf es einiger Überlegungen. Die folgenden Kapitel umfassen die wichtigsten Faktoren:

1.6.1. Sende- und Empfangspuffer

Grundlegend ist, dass sobald der Sendepuffer voll ist, das TCP-Segment gesendet werden muss, damit neue Daten im Puffer eingelagert werden können. Im Gegenzug hierzu ist für den Empfangspuffer anzumerken, dass sobald dieser voll ist, keine weiteren Daten mehr entgegengenommen werden können. Dieser wird dann geleert, sobald es die Ressourcen auf dem jeweiligen System zulassen.

Sie sehen, es ist sehr wichtig für die Effizienz, wie groß die jeweiligen Puffer sind. Sobald der Sendepuffer zu klein gewählt ist (oder nicht größer möglich ist) kann es sein, dass die maximale MTU des physischen Mediums nicht ausgelastet wird. Wie oben bereits beschrieben ist dies uneffizient. Auf der anderen Seite kann das gleiche Problem durch einen zu kleinen Empfangspuffer hervorgerufen werden. Auch hier sind die Segmente kleiner als von der MTU vorgesehen und daher ineffizienter als im Normalfall, da ja der Empfänger keine Segmente empfangen kann, wenn sein Puffer voll ist (auch wenn der Sender größere Segmente schicken könnte).

Die Puffergröße ist von Gerät zu Gerät verschieden. Viele PC-Systeme haben einen Empfangspuffer von acht Kilobyte – Serversysteme hingegen können auch 32, 48 oder mehr Kilobyte zur Verfügung haben.

Es ist also sehr wichtig, dass die Systeme jeweils über den Empfangspuffer des Empfängers informiert werden. Dies geschieht über das Window-Fenster in jedem TCP-Header. Darin trägt jedes Gerät immer die Größe des aktuellen Puffers ein, damit der Sender nicht unabsichtlich zuviel schicken würde (die überschüssigen Daten würden dann nicht ankommen).

1.6.2. MTU-/MRU-Größe

Ebenso wie die Empfangs- und Sendepuffer ist es für TCP sehr wichtig, wie groß die MTU (Maximum Transfer Unit) und die MRU (Maximum Receive Unit) ist. Sobald ein Segment größer als die MTU ist, muss es unweigerlich fragmentiert werden – und wie bereits erwähnt, kostet dies vor allem Zeit.

In den meisten Fällen ist es allerdings so, dass die Größe des TCP-Segmentes hauptsächlich aufgrund der MTU/MRU definiert ist. Sogar die schwächsten Systeme haben meist größere Empfangs- und Sendepuffer als deren MTU/MRU.

In normalen Ethernetsystemen ist die MTU und MRU fix auf 1500 Byte definiert. Das erlaubt also maximal ein TCP-Segment mit 1460 Byte (40 Byte sind ja fix durch den Header definiert!). Bei manchen Wählverbindungen ist es allerdings sinnvoll die MTU niedriger als die MRU zu halten. Der Grund hierfür ist, weil die meisten Systeme im Internet nur Anfragen an Server stellen, von welchen sie dann größere Mengen an Daten beziehen. Durch die Herabsetzung der MTU ist es im Ganzen somit möglich, die Performance für den Einzelnen zu verbessern.

Egal ob nun der Client eine große oder kleine MTU hat, ist es unumgänglich, dass der Sender die MRU des Empfängers kennt. Der zweite wichtige Faktor für den Sender ist seine eigene MTU. Diese beiden Faktoren legen die maximale Segmentgröße fest.

Also ist es auch wichtig für den Sender, die Größe der MRU des Empfängers zu kennen. Die MTU wird ja in jedem Segment, welches transferiert wird, mitgesendet – die MRU hingegen wird in der Aufbauphase der virtuellen Kreisverbindung festgelegt.

Für das sendende System ist es allerdings unmöglich festzustellen, wie die MTU/MRU der Netzwerke zwischen den beiden Systemen ausgelegt ist. Dadurch kann es passieren, dass Segmente trotz aller Berechnungen fragmentiert werden (was ja vermieden werden soll). Deshalb gibt es ein Modul genannt Path MTU Discovery. Hier versucht der Sender ein größtmöglichstes Segment laut seiner MTU zu versenden und verbietet das Fragmentieren (dies kann im Header durch DF festgelegt werden). Sobald das Segment zu einem Router kommt, wo es aufgrund einer kleineren MTU fragmentiert werden müsste, wird eine ICMP-Fehlermeldung zurückgesendet und der Sender verringert die Segmentgröße. Dies geschieht solange, bis keine Fehlermeldungen mehr zurückgesendet werden.

Das Problem an dieser Variante ist, dass manche Geräte wie Firewalls aus Sicherheitsgründen keine ICMP Nachrichten zurücksenden. Deshalb kann es passieren, dass der Sender glaubt, seine angenommene MTU ist bis zum Empfänger möglich. Es ist zwar nicht so, dass die Daten nicht ankommen würden – sie werden aber trotz aller Bemühungen fragmentiert.

1.6.3. Header-Größe

Ein weiterer Faktor bei der Segmentgröße ist die Größe der Header. Im Normalfall ist der Header 40 Byte groß (20 Byte von IP, 20 Byte von TCP). Es gibt allerdings eine Vielzahl an Optionen innerhalb des Headers (z.B. Quality of Service, etc.), die den Header größer werden lassen. Die maximale Größe des Headers liegt bei 120 Byte (jeweils 60 von IP und TCP). Diese Wertzuwächse müssen in die Berechnung der Segmentgröße unbedingt mit einberechnet werden.

1.6.4. Daten-Größe

Der letzte einzuberechnende Faktor ist die Datenmenge selbst. Solange Applikationen viele Daten senden möchten, spielt dies für die Segment-Größe eher eine kleinere Rolle. Die Daten werden an TCP weitergegeben, alle relevanten Faktoren für die maximale Segment-Größe berücksichtigt, die Daten verpackt und via IP gesendet.

Es würde sich allerdings ein Problem ergeben, wenn eine Applikation nur sehr wenig Daten senden möchte – TCP aber wartet, bis eine gewisse Datenmenge zusammenkommt. Bei Applikationen wie Telnet würde dies also heißen, dass eine einzelne Tastatureingabe nicht gesendet wird, sondern erst dann, wenn mehrere zusammenkommen. Bei einer Anwendung wie Telnet ist dies allerdings nicht sinnvoll. Aus diesem Grund exsistiert die Push-Funktion. Sobald eine Applikation weiß, dass nicht mehr Daten folgen werden, kann es TCP mit der Push-Funktion angeben, dass die Daten sofort gesendet werden sollen. Somit ist auch für dieses Problem eine Lösung gefunden worden.

1.7. Flusskontrolle

Wenn zwei Systeme via TCP kommunizieren und Daten austauschen, ist es sehr wichtig, dass TCP eine Möglichkeit hat, um den kontinuierlichen Strom an Daten den jeweiligen Eigenschaften des Empfängers, Senders, Zwischenstationen oder des physikalischen Mediums anzupassen. Nur so kann gewährleistet werden, dass die Daten auch korrekt ankommen.

Die zwei wichtigsten Module – vor allem für den Empfänger – sind hierbei folgende:

Receive window sizing

Ein sendendes System kann immer nur soviele Daten senden, wie der Empfänger es zulässt. Der Empfänger kann durch Anpassen seines Empfangspuffers (welcher ja in jedem TCP-Segment als Receive window mitgeschickt wird) den Sender dazu bewegen mehr oder weniger Daten zu übertragen. Sobald der Empfänger aus irgendwelchen Gründen stark ausgelastet ist, kann er seinen Empfangspuffer niedriger als bisher angeben – der Sender verringert sofort die zu sendende Datenmenge. Sobald wieder genügend Resourcen frei sind, teilt der Empfänger dem Sender einen größeren Empfangspuffer mit - der Sender kann sofort die Datenmenge erhöhen.

Wichtig hierbei ist allerdings, dass der Empfänger den Empfangspuffer nicht plötzlich stark reduzieren sollte, da dadurch Segmente verlorengehen würden (der Sender weiß ja bis zur Bestätigung noch nicht, dass nun die Datentransfermenge reduziert wird).

Sobald der Empfänger den Empfangspuffer auf Null setzt, kann der Sender keine Daten mehr an das System schicken (wenn er dies dennoch tut, werden die Segmente beim Empfänger gelöscht). Dann tritt ein Zeitmechanismus in Kraft. Der Sender versucht nach einer gewissen Zeitspanne erneut Daten zu senden – wenn er keine Besätigung erhält, verdoppelt er die Zeitspanne und versucht es dann abermals. Dies wird solange fortgesetzt, bis ein festgelegtes Maximum erreicht wird (z.B. 64 oder 128 Sekunden).

Das Maximum des Empfangspuffers liegt bei 65 535 Byte, da das Window field im Header des TCP-Segmentes nur 16 bit lang ist. Dies reicht für die meisten Applikationen, jedoch nicht für alle aus (vor allem bei sehr schnellen Netzwerken). Durch die Window Scale Option können sich zwei Systeme ein Window field von 30 bit aushandeln, um einen maximalen Empfangspuffer von einem Gigabyte zur Verwendung zu haben.

In den Anfängen von TCP verursachte dieses Modul das sogenannte Silly Window Syndrome. Die Empfängersysteme hatten teilweise immer nur sehr wenige Daten aus dem Empfangspuffer verarbeitet. Deshalb wurde der freie Empfangspuffer (also das Receive window) kleiner und der Sender musste seine Übertragungsrate vermindern. Deshalb wurde in RFC 1122 festgehalten, dass ein Empfänger nur dann ein Window field größer als Null versenden darf, wenn im Empfangspuffer Platz für ein Segment der maximalen Größe (welches ja vorher bestimmt wird – siehe oben) ist.

Ein ähnliches Problem ergab sich bei den Sendesystemen. Sobald Applikationen nur sehr wenig Daten zu senden hatten, wurde erheblich viel Bandbreite verschwendet. Denn, sobald 10 Byte an Daten in ein 512 Byte großes Segment verpackt werden (der Rest wird nur mit sinnlosen Daten aufgefüllt, da die Segmentgröße immer gewissen mathematischen Teilungsverhältnissen entsprechen muss), ist dies eine enorme Vergeudung. In RFC 896 wurde daher der Nagle algorithm definiert, der besagt, dass Sender eine solch kleine Datenmenge nur dann senden dürfen, wenn alle bisherigen Segmente berreits bestätigt wurden oder bereits genügend Daten für ein „volles“ Segment vorhanden sind.

Sliding receive windows

Hierdurch ist der Sender in der Lage, Daten „vorauszuschicken“. Er wartet also nicht erst auf die Bestätigung des letzten gesendeten Segmentes (Segment A), sondern schickt bereits das nächste an den Sender (Segment B) und vertraut darauf, noch eine Bestätigung über das erste Segment (Segment A) zu erhalten. Der Sender wartet immer auf zwei bestätigte Segmente, bevor er ein drittes „vorauschickt“. Dieses Konzept ist in Grafik 3.18 dargestellt:

Grafik 3.18

Diese beiden Module kommen also eher dem Empfänger des Datenstroms zugute. Auf der anderen Seite muss es aber auch Module geben, die dem Sender ermöglichen die Datenrate zu senken. Im großen und ganzen gibt es hier vier Möglichkeiten:

Congestion window sizing

Ähnlich wie der Empfänger festlegen kann, wieviele Daten er annehmen kann (aus Gründen der Auslastung oder des physischen Mediums), ist dieses Modul das Gegenstück für Geräte zwischen Sender und Empfänger (z.B. Router A). Sobald es die Gegebenheiten nicht zulassen und Router A die Daten nicht in der Geschwindigkeit, wie er sie erhält, weiterleiten kann, schickt er eine ICMP Source Quench Nachricht an den Sender zurück (siehe Kapitel 3.3.4.4.). Dann muss der Sender sein Congestion Window geringer ansetzten – also weniger Daten in Richtung des Empfängers schicken. Tut er das nicht, entstehen nur noch mehr Probleme bei Router A als bisher. Durch Congestion avoidance und Slow Start (siehe unten) wird versucht, die ursprüngliche Datentransferrate wieder herzustellen.

Slow start

Wenn ein User z.B. eine sehr große Datei von einem entfernten System herunterladen möchte, versucht das Sendesystem natürlich sofort die Datei mit voller Geschwindigkeit zu versenden. Wenn aber zwischen die beiden Systemen Geräte mit Engpässen auftreten, würde dies unweigerlich ICMP Fehlermeldungen an den Sender nach sich ziehen (vgl. Beispiel mit Router A im vorigen Abschnitt). Dies wird mit Slow start verhindert. Hier wird mit kleinen Datenmengen begonnen und bei jeder Bestätigung des Empfängers wird die Datenmenge um die gerade gesendete Datenmenge erhöht. Grafik 3.19 soll dies darstellen:

Grafik 3.19

Dies wird solange fortgesetzt, bis entweder Probleme bei Router A auftreten oder bis die sendende Datenmenge gleich dem Empfangspuffer ist.

Congestion avoidance

Wenn aus irgendeinem Grund die Datenmenge, die gesendet werden kann, weniger wird (siehe Congestion window sizing), tritt dieses Modul in Kraft und versucht die ursprüngliche Datentransfermenge wieder herzustellen. Die Funktionsweise ist ähnlich der von Slow start – mit Ausnahme, dass hier alle übertragenen Segmente bestätigt werden müssen, bevor das Congestion window erhöht wird.

Local blocking

Dies ist wohl das einfachste Modul. Hier ist der Sender imstande jegliche Daten, die er von einer Applikation erhält, abzuweisen. Dies muss er machen, sobald TCP nicht mehr in der Lage ist die jeweiligen Daten zu senden (z.B. aufgrund eines Netzwerkproblems).

Hier ist anzumerken, dass TCP eingehenden Datentransfer (von IP) nicht abblocken kann. Die einzige Alternative wäre, dass eingehende Segmente aufgrund eines vollen Empfangspuffers gelöscht werden und somit nicht an die Applikation weitergeleitet werden

[back to top]



Userdaten
User nicht eingeloggt

Gesamtranking
Werbung
Datenbankstand
Autoren:04508
Artikel:00815
Glossar:04116
News:13565
Userbeiträge:16552
Queueeinträge:06245
News Umfrage
Ihre Anforderungen an ein Online-Zeiterfassungs-Produkt?
Mobile Nutzung möglich (Ipone, Android)
Externe API Schnittstelle/Plugins dritter
Zeiterfassung meiner Mitarbeiter
Exportieren in CSV/XLS
Siehe Kommentar



[Results] | [Archiv] Votes: 1151
Comments: 0