2.3.6 Interaktiver Datenaustausch und Nagle-Algorithmus

Nachdem wir bereits wissen, wie TCP-Verbindungen auf- und wieder abgebaut werden, wollen wir uns nun deren eigentlichem Zweck zuwenden, dem Datentransfer. Dabei ist es sinnvoll, zwischen dem z.B. für Telnet, Rlogin und Secure Shell typischen interaktiven Datenaustausch (interactive Data Flow) sowie der u.a. bei FTP, E-Mail und News anzutreffenden geschlossenen Übertragung größerer Datenmengen (Bulk Data Flow) zu unterscheiden. Zunächst soll es um die interaktiven Anwendungen gehen. Die zweite Gruppe wird anschließend in einem eigenen Abschnitt behandelt.

Bei interaktiven Anwendungen überträgt der Klient sehr häufig die vom Nutzer eingegebenen Daten nicht zeilenweise, sondern Zeichen für Zeichen zum Server. Typischerweise wird jedes Byte in einem eigenen TCP-Segment transportiert. Da der Server meist für das Echo verantwortlich ist, sendet er die erhaltenen Bytes gleich wieder zurück. Das führt zum Austausch von (maximal) vier Segmenten:

  1. Datenbyte vom Klienten zum Server
  2. Bestätigung des Servers
  3. Echo vom Server zum Klienten
  4. Bestätigung des Klienten
In der Regel werden Schritt 2 und 3 kombiniert, d.h., die Bestätigung sowie das Echo nutzen dasselbe Paket. Das können wir z.B. bei der Übertragung der Zeichenfolge abc über eine Telnet-Verbindung von yang zu ultra beobachten. Pro Zeichen gehen drei Pakete über das Netz. Die Zeichen selbst finden Sie in der letzten Spalte des snoop-Mitschnitts:
  1   0.00000 yang.informatik.tu-chemnitz.de -> ultra.informatik.tu-chemnitz.de
      TELNET C port=33658 a
  2   0.00058 ultra.informatik.tu-chemnitz.de -> yang.informatik.tu-chemnitz.de
      TELNET R port=33658 a
  3   0.04222 yang.informatik.tu-chemnitz.de -> ultra.informatik.tu-chemnitz.de
      TELNET C port=33658 
  4   0.07647 yang.informatik.tu-chemnitz.de -> ultra.informatik.tu-chemnitz.de
      TELNET C port=33658 b
  5   0.00043 ultra.informatik.tu-chemnitz.de -> yang.informatik.tu-chemnitz.de
      TELNET R port=33658 b
  6   0.04313 yang.informatik.tu-chemnitz.de -> ultra.informatik.tu-chemnitz.de
      TELNET C port=33658 
  7   0.13641 yang.informatik.tu-chemnitz.de -> ultra.informatik.tu-chemnitz.de
      TELNET C port=33658 c
  8   0.00043 ultra.informatik.tu-chemnitz.de -> yang.informatik.tu-chemnitz.de
      TELNET R port=33658 c
  9   0.04307 yang.informatik.tu-chemnitz.de -> ultra.informatik.tu-chemnitz.de
      TELNET C port=33658 
Eine detaillierte Ausgabe [telnet.txt] ist wieder in einer separaten Datei verfügbar.

Die Kombination des zweiten und dritten Schrittes ist möglich, da TCP in der Regel ein ACK nicht sofort, sondern erst nach einer gewissen Verzögerung generiert. Durch dieses delayed ACK wird auf evtl. von der lokalen Applikation bereitgestellte Daten gewartet, die dann zusammen mit dem ACK (also in demselben TCP-Segment) an den Partner verschickt werden. Mitunter finden wir für das gemeinsame Übertragen von Daten und Steuerinformationen auch den Begriff Piggybacking.

Laut RFC 1122 muß die Verzögerung eines ACK unter einer halben Sekunde liegen. Außerdem sollte in einem Strom von Segmenten maximaler Länge (d.h. MSS) wenigstens jedes zweite Paket bestätigt werden. Diese Beschränkungen verfolgen das Ziel, negative Auswirkungen auf die weiter unten ausführlich diskutierten Algorithmen zur Schätzung der Round-Trip Time (RTT) zu verhindern.

Zur Realisierung der Verzögerungen wird in verschiedenen praktischen Implementierungen ein aller 200 ms ablaufender Timer genutzt, so daß die daraus resultierende Wartezeit zwischen 1 und 200 ms variiert. Das ACK wird gesendet, sobald Daten zur Verfügung stehen oder der Timer abgelaufen ist.

Mit Kenntnis dieses Mechanismus lassen sich jetzt die unterschiedlichen Zeitabstände in unserer Beispiel-Sitzung erklären. Das Echo mit dem ACK des Servers folgt wesentlich schneller als das ACK des Klienten, z.B. bei den Paketen 2 und 3 mit 0.00058 s gegenüber 0.04222 s. Das ist logisch, da der Server das Echo im Normalfall viel schneller generiert, als der Mensch die nächste Eingabe vornehmen kann. Beim Klienten läuft der Timer ab, ohne daß die nächsten Zeichen für den Server bereitstehen. Deswegen wird das ACK ohne Daten verschickt. Beim Server dürfte das generell nur sehr selten passieren. In unserem Experiment ist dieser Fall gar nicht eingetreten, da bereits vor Ablauf des Timers Daten zur Verfügung standen, die dann zusammen mit dem ACK so schnell wie möglich gesendet wurden.

Der durch interaktive Anwendungen verursachte Datenverkehr zeichnet sich durch viele sehr kurze Pakete ("Tinygrams") aus, die einen relativ großen Overhead verursachen. Bei Telnet und Rlogin sind sie häufig 40 oder 41 Bytes lang, d.h., hinter den Standard-Köpfen von IP und TCP wird entweder gar kein oder genau ein Byte transportiert.
Bei Secure Shell sind die Datagramme meist etwas länger, wobei die konkrete Byteanzahl vom intern verwendeten Binär-Protokoll, den eingesetzten kryptographischen Algorithmen sowie der im Standardfall genutzten Komprimierung abhängt.

Im LAN stellt dieser Overhead meist kein ernstes Problem dar, da die Bandbreite ausreicht. Anders sieht das im WAN-Bereich aus. Dort können die "Tinygrams" relativ schnell zum Paketstau führen. Eine einfache und elegante Lösung dieses Problems beschreibt der nach seinem Autor benannte Nagle-Algorithmus, der im RFC 896 vorgeschlagen wurde. Der Kerngedanke findet sich u.a. sehr klar im RFC 1122 oder bei Comer:

Sofern es für eine Verbindung noch unbestätigte Segmente gibt, puffert der Sender sämtliche Nutzerdaten, bis entweder alle noch ausstehenden Bestätigungen eingetroffen sind oder genug Daten gesammelt wurden, um ein Paket der Maximalgröße (MSS) versenden zu können. Diese Regel gilt unabhängig davon, ob der Nutzer das unverzügliche Senden durch eine Push-Operation angefordert hat oder nicht.

Das durch ein verzögertes Senden erzwungene Ansammeln von Daten wird auch als Clumping bezeichnet.

Der Algorithmus arbeitet adaptiv, d.h., die Verzögerungen hängen jeweils von der aktuellen Performance des Netzes ab. Je schneller die Bestätigungen eintreffen, desto schneller werden die Daten gesendet. Berechnungen finden hierbei nicht statt. Timer sind ebenfalls nicht nötig. Deshalb bezeichnet man das Verfahren als self-clocking.

Ist die Anwendung im Vergleich zum Netz sehr langsam (typisch für interaktive Anwendungen), dann sind die Segmente klein und werden ohne große Verzögerung übertragen. Anderenfalls, also wenn die Anwendung gegenüber dem Netz relativ schnell ist (z.B. ein Filetransfer), bildet TCP große Segmente.

Da es allerdings Anwendungen gibt (z.B. X-Windows), die eine Versendung der Pakete mit maximaler Geschwindigkeit erfordern, muß jede TCP-Implementierung laut RFC 1122 die separate Deaktivierung des Nagle-Algorithmus für die einzelnen Verbindungen gestatten.


© Holger Trapp, 26.5.1998