🤝 Рукостискання TCP/IP та керування перевантаженням — повільний старт, AIMD
Спостерігайте справжнє потрійне рукостискання TCP (SYN → SYN-ACK → ACK) зі справжніми порядковими номерами, потім живу симуляцію вікна перевантаження AIMD: експоненційний повільний старт, лінійне уникнення перевантаження та мультиплікативне зменшення при втраті пакетів.
Про рукостискання TCP та керування перевантаженням
Кожне з'єднання TCP починається з потрійного рукостискання. Клієнт обирає випадковий 32-бітний початковий порядковий номер (ISN) і надсилає сегмент із встановленим прапорцем SYN. Сервер відповідає власним випадковим ISN та встановленим прапорцем ACK, підтверджуючи порядковий номер клієнта, повторюючи ISN+1 у своєму полі підтвердження — один сегмент виконує дві роботи, звідси «SYN-ACK». Клієнт завершує, надсилаючи ACK, що підтверджує ISN+1 сервера. Лише тоді з'єднання ВСТАНОВЛЕНЕ з обох сторін.
Коли дані починають надходити, TCP має вирішити, як швидко надсилати, не перевантажуючи мережу — робота керування перевантаженням. Алгоритм Ван Джейкобсона, що датується 1988 роком і досі є основою сучасного TCP, починає обережно: вікно перевантаження (cwnd) починається з одного сегмента й подвоюється кожен час обороту («повільний старт»), зростаючи експоненційно. Коли cwnd досягає порогу (ssthresh), TCP перемикається на «уникнення перевантаження», додаючи лише один сегмент за оборот — адитивне збільшення. Коли виявлено втрату, TCP трактує це як сигнал перевантаження: ssthresh встановлюється на половину поточного cwnd, cwnd колапсує до малого значення, і експоненційний підйом починається знову. Цей патерн адитивного збільшення/мультиплікативного зменшення (AIMD) і породжує характерний пилкоподібний графік пропускної здатності TCP.
Оскільки cwnd фактично обмежує кількість непідтверджених сегментів у польоті, пропускна здатність обмежена приблизно cwnd·MSS / RTT — високий RTT або часті втрати пригнічують її. Відома формула Матіса апроксимує усталену пропускну здатність TCP як обернено пропорційну RTT та квадратному кореню з рівня втрат.
Часті запитання
Чому TCP потребує трьох повідомлень лише для встановлення з'єднання?
Обидві сторони мають узгодити й підтвердити початковий порядковий номер одна одної, перш ніж будь-яка зможе надійно відстежувати, які байти прибули. Два повідомлення (SYN, SYN-ACK) дозволили б серверу підтвердити ISN клієнта й запропонувати власний, але сервер не мав би підтвердження, що клієнт справді отримав його ISN — третє повідомлення (ACK) закриває цю прогалину.
Що таке вікно перевантаження і чим воно відрізняється від вікна прийому?
Вікно прийому — це отримувач, що повідомляє відправнику, скільки в нього місця в буфері — обмеження керування потоком. Вікно перевантаження (cwnd) — власна оцінка відправника того, скільки даних мережевий шлях може поглинути без втрат — обмеження керування перевантаженням.
Чому повільний старт зростає експоненційно, якщо він мав би бути «повільним»?
«Повільний» стосується початку з одного сегмента, а не миттєвого надсилання на повній швидкості — але саме зростання подвоюється кожен RTT (1, 2, 4, 8, 16…), що є експоненційним.
Що викликає «подію втрати» у справжньому TCP — і чому ця симуляція моделює її як випадкову?
Справжній TCP виявляє втрату через тайм-аут повторної передачі або через три дублікатних ACK. Ця симуляція абстрагує обидва в єдину ймовірність втрати на RTT, щоб можна було безпосередньо побачити, як частота втрат формує пилку.
Що таке AIMD і чому це «правильна» форма керування перевантаженням?
Адитивне збільшення, мультиплікативне зменшення збільшує cwnd на фіксовану величину кожен RTT, коли все гаразд, і скорочує його на фіксовану частку при виявленні втрати. Теорія керування показує, що AIMD сходиться до справедливого розподілу пропускної здатності серед конкуруючих потоків.
Чи сучасний TCP все ще використовує саме цей алгоритм?
Основна форма AIMD все ще присутня, але виробничі стеки додають вдосконалення: TCP Reno додає швидке відновлення, CUBIC (за замовчуванням у Linux) зростає як кубічна функція часу, а BBR оцінює вузьке місце пропускної здатності шляху безпосередньо.
Чому високий RTT шкодить пропускній здатності навіть без втрати пакетів?
Оскільки cwnd зростає раз за оборот, з'єднання з RTT 300 мс потребує втричі довше часу для досягнення того самого розміру вікна, ніж з RTT 100 мс. Пропускна здатність обмежена приблизно cwnd·MSS / RTT.
Що таке формула Матіса і наскільки вона точна?
Формула Матіса апроксимує усталену пропускну здатність TCP як MSS / (RTT · √(рівень втрат)). Це широко використовувана приблизна оцінка, але вона припускає лише усталене уникнення перевантаження — ігнорує повільний старт, тайм-аути та обмеження вікна прийому.
Чи може з'єднання «застрягти» в повільному старті назавжди?
Ні — повільний старт завжди закінчується, або досягаючи ssthresh і перемикаючись на уникнення перевантаження, або спершу натикаючись на подію втрати, яка встановлює новий (нижчий) ssthresh і перезапускає повільний старт з малого вікна.