Strona głównaArtykułyInternet i sieci

Przełączanie TCP/IP i kontrola zagęszczenia

Trzy pakiety do otwarcia połączenia, a potem szpilka wzrostu eksponencjalnego i nagle ujemnej zmiany aby uniknąć upadku całego internetu pod wpływem własnych danych.

mysimulator teamZaktualizowano — czerwiec 2026≈ 9 min czytania▶ Otwórz symulację

Przed przeniesieniem pierwszego bajtu danych

TCP jest protokołem orientowanym w połączeniach, zgrubnie na IP, który nie jest — IP prosto przekierowuje pojedyncze pakety ku adresowi bez pamięci o tym, co przedtem ani co nastąpiło. TCP musi budować iluzję wiarygodnej, uporządkowanej, połączonych strumieni na podstawie tego zapomnianego substratu, i zaczyna od tego, że obie końce zgadzają się na miejsce rozpoczęcia strumienia. Ta zgoda to trzykrotna dżentonka, a ta symulacja animuje ją pakiet po pakiecie przed przejściem do części, której większość wyjaśnień pomija: co się dzieje z przechodnictwem połączenia, gdy rzeczywiście przepływa dane i sieć napotkuje zagęszczenie.

demo na żywo · powiązana symulacja● LIVE

SYN, SYN-ACK, ACK

Każdy bokTCP połączenia śledzi swój własny numer szeregowy — licznik identyfikujący przesunięcie bajtowe strumienia, który chce wysłać — a całe podeszwowanie jest skonstruowane do wymiany i potwierdzenia tych wartości początkowych:

klient -> serwer: SYN, seq = x (Zamieram rozpocząć od bajtu x) serwer -> klient: SYN-ACK, seq = y, ack = x + 1 (Zamieram rozpocząć od y; potwierdzam twoje x) klient -> serwer: ACK, ack = y + 1 (Potwierdzam twoje y) Po tej wymianie obydwa boki wiedzą o numerze szeregowym początkowym drugiej strony i potwierdzili go, co pozwala na śledzenie każdego kolejnego segmentu danych, umieszczanie ich w odpowiedniej kolejności oraz potwierdzenie otrzymania nawet jeśli protokół IP może dostarczać podstawowe paczki nieporządanymi lub całkowicie usunąć niektóre z nich. Podeszwowanie to również negocjuje parametry połączenia — wielkość okna, maksymalny rozmiar segmentu, wsparcie dla potwierdzeń wybiorowych — załączane na tym samym trzech pakietach, dlatego powolne lub utraty podeszwowanie opóźnia nie tylko rozpoczęcie połączenia, ale także negocjowane cechy, które kształtują wszystko co nastąpi potem.

client -> server:  SYN,     seq = x                (I plan to start at byte x)
server -> client:  SYN-ACK, seq = y, ack = x + 1   (I plan to start at y;
                                                    I confirm your x)
client -> server:  ACK,     ack = y + 1             (I confirm your y)

Po nawiązaniu połączenia: okno zagęszczania

LIVE połączenie TCP nie może przesyłać danych tak szybko, jak to pozwala link nadawcy — gdzieś na trasie może być wolniejszy link lub zatłoczony router, a wysyłanie szybciej niż sieć jest w stanie założyć tylko wypełnia bufora aż do przepełnienia i utraty pakietów. Odpowiedzią TCP jest okno zagęszczania (cwnd): ograniczenie nadawcy na ilość niepotwierdzonych bajtów, które mogą być w trakcie przesyłania, dostosowywane ciągle na podstawie tego, czy pakety są poprawnie otrzymane lub utracone — to jest AIMD (additive-increase multiplicative-decrease), a szpiccetka, którą tworzy, to druga część demonstracji w czasie rzeczywistym.

Slow start: wykładniczy wzrost, mimo nazwy

Niedługo po przeprowadzeniu ręcznie wypukłej (handshake), TCP nie ma żadnych informacji na temat pojemności ścieżki, więc zaczyna konserwatywnie — ale szybko rośnie. Slow start podwójnia cwnd około co RTT, ponieważ każda potwierdzona sekcja zwiększa cwnd o wartość jednej sekcji, a w ciągu jednego RTT cała okno zawiera się w potwierdzonych sekcjach:

slow start (podczas gdy cwnd cwnd około podwójny co RTT // to jest wzrost wykładniczy mimo nazwy „slow start” - // jest „spowolniony” tylko w porównaniu do wysłania całego okna od razu Ten proces kontynuuje się, dopóki cwnd nie osiągnie próg (ssthresh) — zazwyczaj ustawionego na podstawie poprzedniego wydarzenia straty — lub aż do momentu wykrycia strony, w którym TCP przełącza tryby.

slow start (while cwnd < ssthresh):
  on each ACK received:  cwnd += 1 segment
  // an entire cwnd of segments ACKed within ~1 RTT => cwnd roughly doubles per RTT
  // this is exponential growth despite the name "slow start" -
  // it's "slow" only relative to sending the whole window at once

Unikanie zagęszczenia: zwiększanie dodawanej w sposób addytywny

Po przekroczeniu ssthresh TCP przyjmuje założenie, że jest blisko rzeczywistej pojemności ścieżki i przełącza się na ostrożne liniowe zwiększanie — zwiększając cwnd o około jedno segmenty na czas pełnego przepływu wiadomości zamiast dla każdego potwierdzenia otrzymania (ACK), dwaustoskawo sprawdzając, czy istnieje jeszcze jakieś wolne miejsce:

congestion avoidance (cwnd >= ssthresh):
  on each full window of ACKs (~1 RTT):  cwnd += 1 segment
  // linear growth - the "additive increase" half of AIMD

Strata: zmniejszenie mnożone

Pakiet zakończony strażą (wykryta przez either retransmisji czasu wyjścia, lub bardziej obwączona przez powtórzone potwierdzenia oznaczające przestój w otrzymanym strumieniu) jest niejawnym sygnałem TCP, że przekroczył rzeczywistą pojemność sieci — brak jasnej notyfikacji zatargu, TCP wnioskuje o zatarg na podstawie strony. Reakcja to agresywne zmniejszenie mnożone, a nie łagodna korekcja:

w momencie wykrycia straty: ssthresh = cwnd / 2 cwnd = ssthresh (lub cwnd = 1 segment, dla czasu wyjścia - pełny restart z powrotem do startu wolnego) -> wznowienie w fazie unikania zatargu od zmniejszonego o połowe wartości Asymetrię — zwiększanie dodawane, zmniejszanie mnożone — jest świadomie zaplanowana i to co sprawia, że AIMD konverguje równomiernie i stabilnie nawet wtedy, gdy wiele niezależnych połączeń TCP dzieli jedno ograniczone łącze bez koordynacji między nimi: liniowe zwiększanie jest ostrożne dość, aby nie przekroczyć pojemności o znaczną ilość przed kolejnym sygnałem strony, a zmniejszanie mnożone w momencie straty jest szybkie do wystarczającego odstępu, aby pusty kolejnik zatargowany pusta szybko, zamiast ponownie przekraczać go. Powtarzający się cykl wzrostu liniowego, a następnie zmniejszenia mnożone w momencie straty tworzy charakterystyczną grafikę przebiegu przepustowości w kształcie szpikulca, która jest drugą połową tego symulacji live plot, a to jest jedna z najważniejszych części projektowania algorytmu na całym internetie — to powoduje, że zatargowane łącze degraduje się łagodnie w delikatne, sprawiedliwe przepustowość dołączanej, zamiast klesnąć w zatarg.

on loss detected:
  ssthresh = cwnd / 2
  cwnd     = ssthresh          (or cwnd = 1 segment, for a timeout -
                                 a full restart back to slow start)
  -> resume in congestion avoidance from the halved value

Często zadawane pytania

Dlaczego TCP potrzebuje trzech pakietów do zainicjowania połączenia zamiast jednego?

Bo obie strony muszą uzyskać zgody na numer sekwencyjny, a każda strona musi mieć dowód, że druga strona rzeczywiście otrzymała swój numer, a nie tylko go wysłała. SYN przedstawia numer sekwencyjny klienta, SYN-ACK przedstawia numer sekwencyjny serwera i potwierdza numer klienta, a końcowy ACK potwierdza numer serwera — po trzech pakietach obie strony mają wspólnie potwierdzony, nie tylko wspólnie stwierdzony punkt początkowy.

Jeśli start szybki rosnie w wykładniczy sposób, dlaczego jest nazywany 'spowolnionym'?

Jest spowolniony tylko w stosunku do alternatywy wysyłania pełnej dużej liczby pakietów natychmiast, bez żadnego wzrostu, co wcześniejsze, bardziej prostokrotne implementacje TCP robily i które wiarygodnie zaskakiwały intermedialne routerzy. W porównaniu z tym, od jednego segmentu i podwójne się w każdym odcinku powrotnej trasji jest konserwatywnym wyborem — nawet jeśli w absolutnych wyższych wymiarach wzrost jest wykładniczy.

Dlaczego TCP zmniejsza szybkość wysyłania pół na stratę pakietu zamiast mniejszej korekcji?

Bo TCP nie ma jasnej sygnału dla tego, jak zaopatrzony jest sieć — stracony pakiet to jedyna odpowiedzialność, którą otrzymuje. Po detekcji straty sieć może już być znacznie zaopatrzona. Duża i szybka zmiana (zmniejszenie mnożone) wyciśnia szybko koleję zablokowaną; potem wolne, liniowe wzrost (zwiększanie dodawane) jest to, co sprawia, że algorytm konverguje do stabilnej, równo podzielonej części przepustowości bez powtarzających się nadmiarów i ponownego spowodowania straty.

Wypróbuj na żywo

Wszystko powyżej działa bezpośrednio w Twojej przeglądarce — otwórz TCP/IP Handshake & Congestion Control — Slow Start, AIMD i zmieniaj parametry podczas działania. Nic nie jest instalowane ani przesyłane na serwer, cały model działa w jednej karcie.

▶ Otwórz symulację TCP/IP Handshake & Congestion Control — Slow Start, AIMD

Co znalazłeś?

Dodaj kroki odtworzenia (opcjonalnie)