Kontrola Przepływu TCP

Mechanizm przesuwnego okna i kontrola przepływu w połączeniach TCP.

Wprowadzenie: Problem Szybkiego Producenta i Wolnego Konsumenta

Wyobraź sobie szybką linię produkcyjną w rozlewni, która może napełniać tysiące butelek na minutę. Na końcu taśmy produkcyjnej stoi jeden pracownik, którego zadaniem jest ręczne wkładanie każdej butelki do pudełka. Maszyna do butelkowania (nadawca) jest niesamowicie szybka, ale pracownik (odbiorca) może obsługiwać butelki w znacznie wolniejszym tempie. Jeśli maszyna będzie działać na pełnych obrotach bez żadnej koordynacji, butelki szybko zaczną się piętrzyć, spadać z taśmy i tłuc. Informacja, w tym przypadku napój w butelkach, zostanie utracona.

To jest fundamentalne wyzwanie, które Kontrola Przepływu w TCP ma za zadanie rozwiązać. W sieci bardzo często zdarza się, że komputer wysyłający jest w stanie generować i wysyłać dane znacznie szybciej, niż komputer odbierający może je przetworzyć. Potężny serwer może transmitować dane z prędkością gigabitów na sekundę, podczas gdy urządzenie odbiorcze, być może smartfon lub starszy laptop, może być zajęte innymi zadaniami i nie być w stanie nadążyć.

Bez systemu zarządzania, szybki nadawca szybko przytłoczyłby wolnego odbiorcę, zalewając jego bufory pamięci danymi. Wszelkie nowe dane, które dotarłyby, gdy bufor jest pełny, musiałyby zostać odrzucone. Prowadziłoby to do masowej utraty pakietów, wywołując ciągłe retransmisje i poważnie degradując wydajność połączenia. Kontrola Przepływu w TCP to eleganckie rozwiązanie tego problemu. Jest to zbiór zasad, który pozwala odbiorcy informować nadawcę, ile dokładnie danych jest gotów przyjąć w danym momencie, skutecznie działając jak dławik, aby uniemożliwić nadawcy zbyt szybką transmisję. Zapewnia to, że cyfrowa konwersacja odbywa się w tempie, które odbiorca może komfortowo obsłużyć, zapobiegając utracie danych z powodu przepełnienia bufora.

Główne Komponenty Kontroli Przepływu

Kontrola przepływu w TCP opiera się na dwóch kluczowych komponentach działających w tandemie: tymczasowym obszarze przechowywania po stronie odbiorcy i mechanizmie komunikacyjnym w nagłówku TCP do zarządzania tym obszarem.

1. Bufor Odbiorczy TCP

Dla każdego połączenia TCP system operacyjny odbiorcy przydziela blok pamięci zwany buforem odbiorczym. Bufor ten działa jak tymczasowy obszar przechowywania przychodzących danych. Gdy segmenty TCP docierają, ich dane są umieszczane w tym buforze. Aplikacja działająca na odbiorcy (np. przeglądarka internetowa lub klient e-mail) odczytuje dane z tego bufora we własnym tempie.

Pomyśl o buforze odbiorczym jak o skrzynce na listy. Sieć to listonosz, wrzucający listy (segmenty danych) do skrzynki. Aplikacja to odbiorca, który podchodzi do skrzynki i odbiera listy, gdy ma na to czas. Kontrola przepływu jest potrzebna, aby upewnić się, że listonosz nie próbuje wcisnąć więcej listów do skrzynki, niż jest w stanie pomieścić. Ilość wolnego miejsca w tym buforze to krytyczna informacja, którą odbiorca musi przekazać nadawcy.

2. Pole Okna Odbiorczego (rwnd)

Komunikacja o ilości miejsca w buforze odbywa się za pośrednictwem pola Rozmiar Okna (często nazywanego Oknem Odbiorczym lub 'rwnd') w . To 16-bitowe pole pozwala odbiorcy ogłosić, ile ma aktualnie dostępnego miejsca w swoim buforze odbiorczym, w bajtach.

Z każdym segmentem potwierdzającym (ACK) wysyłanym z powrotem do nadawcy, odbiorca dołącza aktualną wartość swojego 'rwnd'. Na przykład, jeśli bufor ma całkowitą pojemność 64 KB, a obecnie znajduje się w nim 10 KB danych oczekujących na odczytanie przez aplikację, odbiorca ogłosi 'rwnd' o wartości 54 KB. Po otrzymaniu tej informacji nadawca wie, że nie wolno mu wysłać więcej niż 54 KB nowych danych, zanim otrzyma kolejną aktualizację. Ta dynamiczna informacja tworzy pętlę sprzężenia zwrotnego, która stale dostosowuje szybkość transmisji do możliwości odbiorcy.

Wyjaśnienie Mechanizmu Przesuwnego Okna

Proces zarządzania transmisją danych w oparciu o ogłoszony rozmiar okna odbiorczego nazywany jest mechanizmem przesuwnego okna. Jest to jedna z najgenialniejszych i fundamentalnych koncepcji w sieciach komputerowych, ponieważ pozwala na wydajny i niezawodny transfer danych bez konieczności czekania na potwierdzenie każdego wysłanego pakietu.

Okno jest koncepcyjnym zakresem numerów sekwencyjnych, które nadawca ma obecnie prawo przesłać. W miarę wysyłania i potwierdzania danych, to okno przesuwa się do przodu wzdłuż przestrzeni numerów sekwencyjnych całego strumienia danych.

Kluczowa Terminologia Okna (Strona Nadawcy)

Zdefiniujmy kilka zmiennych, które nadawca śledzi dla swojego okna wysyłania:

  • Ostatni Wysłany Bajt (LBS): Numer sekwencyjny ostatniego bajtu danych, który został wysłany.
  • Ostatni Potwierdzony Bajt (LBA): Numer sekwencyjny ostatniego bajtu danych, który odbiorca pomyślnie potwierdził. Wszystkie bajty przed nim uważa się za pomyślnie dostarczone.
  • Ogłoszony Rozmiar Okna (rwnd): Najnowsza wartość rozmiaru okna otrzymana od odbiorcy.

Na tej podstawie nadawca oblicza swoje efektywne okno wysyłania, czyli ilość nowych danych, które może wysłać:

Okno Efektywne=rwnd(LBSLBA)\text{Okno Efektywne} = \text{rwnd} - (\text{LBS} - \text{LBA})

Jest to ogłoszone okno pomniejszone o ilość danych już będących w drodze (wysłanych, ale jeszcze niepotwierdzonych).

Przewodnik po Procesie Przesuwnego Okna

Przejdźmy przez prosty scenariusz transferu pliku, aby zobaczyć przesuwne okno w akcji.

  1. Stan Początkowy: Połączenie jest w stanie ESTABLISHED. Klient (nadawca) chce wysłać plik o wielkości 10 000 bajtów do serwera (odbiorcy). Serwer ogłasza początkowe okno odbiorcze ('rwnd') o wielkości 4 000 bajtów. Obie strony zsynchronizowały swoje numery sekwencyjne, zaczynając od 1. Klient ma puste okno wysyłania; może wysłać do 4 000 bajtów.
  2. Nadawca Transmituje Dane: Aplikacja nadawcy dostarcza dane. Nadawca tworzy kilka segmentów. Dla uproszczenia załóżmy, że tworzy dwa segmenty po 1 000 bajtów każdy i wysyła je natychmiast.
    • Segment 1: Zawiera bajty 1-1000.
    • Segment 2: Zawiera bajty 1001-2000.
    Ostatni Wysłany Bajt (LBS) klienta to teraz 2000. Ma on 2 000 bajtów danych w drodze (wysłanych, ale jeszcze niepotwierdzonych). Jego użyteczne okno skurczyło się do 40002000=20004000 - 2000 = 2000 bajtów. Może jeszcze wysłać 2000 bajtów, zanim będzie musiał się zatrzymać i czekać na ACK.
  3. Odbiorca Potwierdza Dane: Serwer otrzymuje oba segmenty poprawnie. Jego aplikacja odczytuje pierwsze 1000 bajtów z bufora, zwalniając miejsce. Serwer odsyła segment ACK.
    • Numer Potwierdzenia: 20012001 (potwierdzając odbiór wszystkich bajtów do 2000 i prosząc o następny).
    • Rozmiar Okna: Jego całkowity bufor to 4000 bajtów. Otrzymał bajty 1001-2000, które są w buforze, ale aplikacja odczytała pierwsze 1000. Powiedzmy, że ma teraz 3000 bajtów wolnego miejsca. Ogłasza 'rwnd' = 3000.
  4. Nadawca Przesuwa Okno: Klient otrzymuje ACK. Teraz wie, że bajty 1-2000 zostały pomyślnie dostarczone. Może "przesunąć" swoje okno do przodu.
    • Jego Ostatni Potwierdzony Bajt (LBA) to teraz 2000.
    • Ilość danych w drodze staje się 0 (LBSLBA=20002000=0LBS - LBA = 2000 - 2000 = 0).
    • Aktualizuje również swoje rozumienie okna odbiorcy do nowo ogłoszonej wartości 'rwnd' równej 3000.
    • Jego użyteczne okno wynosi teraz pełne 3 000 bajtów. Może natychmiast wysłać bajty od 2001 do 5000.

Ten proces wysyłania danych, aktualizowania ilości danych w drodze, otrzymywania potwierdzeń i przesuwania okna powtarza się w sposób ciągły, pozwalając na płynny, wydajny i niezawodny przepływ danych, który automatycznie dostosowuje się do zdolności odbiorcy do ich przetwarzania.

Przypadki Specjalne i Problemy w Kontroli Przepływu

Mechanizm przesuwnego okna jest solidny, ale może pojawić się kilka skrajnych przypadków i potencjalnych nieefektywności, na które TCP ma określone rozwiązania.

Problem Okna Zerowego i Sondy

Co się stanie, jeśli aplikacja odbiorcy przestanie odczytywać dane, a jego bufor odbiorczy całkowicie się zapełni? W takim przypadku odbiorca ogłosi rozmiar okna równy 0. Jest to jasny sygnał dla nadawcy: NATYCHMIAST PRZESTAŃ WYSYŁAĆ DANE. Nadawca musi się do tego zastosować i wstrzyma transmisję.

Stwarza to potencjalny impas. Nadawca czeka teraz na aktualizację z niezerowym oknem. Odbiorca wyśle taką aktualizację dopiero, gdy jego aplikacja odczyta dane, ale segment zawierający tę aktualizację okna może zaginąć w sieci. Gdyby zaginął, nadawca czekałby wiecznie, a połączenie utknęłoby w martwym punkcie.

Aby temu zapobiec, gdy nadawca otrzyma ogłoszenie o oknie zerowym, uruchamia licznik czasu podtrzymania (ang. persist timer). Gdy licznik wygaśnie, nadawca wysyła malutki, jednobajtowy segment zwany Sondą Okna Zerowego (ang. Zero-Window Probe). Sonda ta zmusza odbiorcę do odpowiedzi z potwierdzeniem zawierającym jego aktualny rozmiar okna. Jeśli nadal wynosi on zero, nadawca resetuje licznik i próbuje ponownie później. Jeśli jest niezerowy, nadawca może wznowić transmisję. Mechanizm sondowania zapewnia, że utracona aktualizacja okna nie spowoduje trwałego zablokowania połączenia.

Syndrom Głupiego Okna (SWS)

Syndrom Głupiego Okna to stan, który może poważnie zdegradować wydajność TCP, powodując transmisję wielu bardzo małych segmentów danych, co jest wysoce nieefektywne. Może być spowodowany zarówno przez "głupiego" odbiorcę, jak i "głupiego" nadawcę.

  • Głupi Odbiorca: Wyobraź sobie, że aplikacja odbiorcy odczytuje dane bajt po bajcie. Po każdym odczycie zwalniany jest jeden bajt przestrzeni buforowej. Naiwny odbiorca mógłby natychmiast wysłać aktualizację okna, ogłaszając okno o wielkości zaledwie 1 bajta. Nadawca posłusznie wysłałby segment jednobajtowy, który ma 20-bajtowy nagłówek TCP i 20-bajtowy nagłówek IP. Transmitowanie 1 bajtu danych przy użyciu 40-bajtowego opakowania to ogromne marnotrawstwo przepustowości.
    Rozwiązanie: Odbiorca powinien poczekać, aż zwolni się znacząca ilość miejsca w buforze (np. połowa bufora lub co najmniej jeden MSS), zanim ogłosi większe okno.
  • Głupi Nadawca: Wyobraź sobie, że aplikacja nadawcy generuje dane bajt po bajcie (np. z naciśnięć klawiszy w zdalnej sesji terminalowej). Naiwny nadawca mógłby natychmiast wysyłać każdy bajt jako osobny segment TCP. Ponownie skutkuje to ogromnym narzutem (40 bajtów nagłówka na 1 bajt danych).
    Rozwiązanie: . Pozwala on nadawcy na wysłanie pierwszego małego segmentu, ale następnie przechowuje wszelkie kolejne małe fragmenty danych w swoim buforze. Czeka na powrót potwierdzenia dla pierwszego segmentu, zanim spakuje wszystkie zbuforowane małe fragmenty w jeden, większy segment i go wyśle.

Dostosowanie do Nowoczesnych Sieci: Opcja Skalowania Okna

Oryginalny projekt TCP, z jego 16-bitowym polem Rozmiar Okna, ograniczał maksymalne okno odbiorcze do 65 535 bajtów (64 KB). We wczesnych dniach internetu była to ogromna ilość danych. Jednak w nowoczesnych, szybkich i dalekosiężnych sieciach stało się to poważnym wąskim gardłem wydajności.

Ograniczającym czynnikiem jest pojęcie zwane Iloczynem Przepustowości i Opóźnienia (BDP). BDP oblicza maksymalną ilość danych, jaka może znajdować się "w drodze" w rurze sieciowej w danym momencie.

BDP=Przepustowosˊcˊ×Czas Obiegu (RTT)\text{BDP} = \text{Przepustowość} \times \text{Czas Obiegu (RTT)}

Wyobraźmy sobie połączenie danych jako fizyczną rurę. Przepustowość to jej średnica, a Czas Obiegu (RTT) to jej długość. BDP to objętość rury. Aby osiągnąć maksymalną przepustowość, nadawca musi wypełnić całą rurę danymi. Oznacza to, że jego okno wysyłania musi być co najmniej tak duże jak BDP.

Dla połączenia z Warszawy do Nowego Jorku o przepustowości 1 Gb/s i RTT 100 ms, BDP wynosi około 12,5 MB. Okno 64 KB to jak próba napełnienia basenu olimpijskiego za pomocą węża ogrodowego, jest rażąco niewystarczające. Nadawca wysłałby swoje maleńkie okno 64 KB danych, a następnie musiałby bezczynnie czekać, aż te dane przemierzą Atlantyk i aż wróci potwierdzenie, zanim mógłby wysłać więcej.

Aby rozwiązać ten problem, wprowadzono opcję Skalowania Okna TCP. Podczas trójetapowego uzgadniania obie strony mogą negocjować współczynnik skali (od 0 do 14). Ten współczynnik to liczba bitów, o którą należy przesunąć w lewo wartość z 16-bitowego pola Rozmiar Okna. Na przykład współczynnik skali 8 oznacza, że wartość z pola Rozmiar Okna należy pomnożyć przez 282^8 (256). Pozwala to na uzyskanie znacznie większego efektywnego okna odbiorczego, do 1 Gigabajta, co umożliwia TCP pełne wykorzystanie pojemności nowoczesnych sieci.

    Kontrola Przepływu TCP | Teleinf Edu