Ключові таємниці TCP-з'єднань мережевого брокера пакетів: розвінчано необхідність потрійного рукостискання

Налаштування TCP-з'єднання
Коли ми переглядаємо веб-сторінки, надсилаємо електронні листи або граємо в онлайн-гру, ми часто не замислюємося про складне мережеве з'єднання, яке за цим стоїть. Однак саме ці, здавалося б, невеликі кроки забезпечують стабільний зв'язок між нами та сервером. Одним з найважливіших кроків є налаштування TCP-з'єднання, а основою цього є тристороннє рукостискання.

У цій статті детально обговорюватиметься принцип, процес та важливість тристороннього рукостискання. Крок за кроком ми пояснимо, чому потрібне тристороннє рукостискання, як воно забезпечує стабільність та надійність з'єднання, а також наскільки воно важливе для передачі даних. Глибше розуміння тристороннього рукостискання допоможе нам краще зрозуміти основні механізми мережевого зв'язку та отримати чіткіше уявлення про надійність TCP-з'єднань.

Процес тристороннього рукостискання TCP та переходи станів
TCP — це транспортний протокол, орієнтований на з'єднання, який вимагає встановлення з'єднання перед передачею даних. Цей процес встановлення з'єднання здійснюється за допомогою тристороннього рукостискання.

 Тристороннє рукостискання TCP

Давайте детальніше розглянемо TCP-пакети, які надсилаються в кожному з'єднанні.

Спочатку і клієнт, і сервер ЗАЧИНЕНІ. Спочатку сервер активно прослуховує порт і знаходиться у стані LISTEN, що означає, що сервер має бути запущений. Далі клієнт готовий розпочати доступ до веб-сторінки. Йому потрібно встановити з'єднання із сервером. Формат першого пакета з'єднання такий:

 SYN-пакет

Коли клієнт ініціює з'єднання, він генерує випадковий початковий порядковий номер (client_isn) та поміщає його в поле "Порядковий номер" заголовка TCP. Одночасно клієнт встановлює прапорець SYN у положення 1, щоб вказати, що вихідний пакет є SYN-пакетом. Клієнт вказує, що він бажає встановити з'єднання із сервером, надсилаючи перший SYN-пакет на сервер. Цей пакет не містить даних прикладного рівня (тобто надісланих даних). На цьому етапі статус клієнта позначається як SYN-SENT.

Пакет SYN+ACK

Коли сервер отримує SYN-пакет від клієнта, він випадковим чином ініціалізує свій власний серійний номер (server_isn), а потім поміщає цей номер у поле «Серійний номер» заголовка TCP. Далі сервер вводить client_isn + 1 у поле «Номер підтвердження» та встановлює обидва біти SYN та ACK у значення 1. Нарешті, сервер надсилає клієнту пакет, який не містить даних прикладного рівня (і даних для надсилання сервером). У цей час сервер знаходиться у стані SYN-RCVD.

Пакет ACK

Після того, як клієнт отримає пакет від сервера, йому потрібно виконати такі оптимізації, щоб відповісти на остаточний пакет відповіді: по-перше, клієнт встановлює біт ACK TCP-заголовка пакета відповіді на 1; по-друге, клієнт вводить значення server_isn + 1 у поле "Номер підтвердження відповіді"; нарешті, клієнт надсилає пакет на сервер. Цей пакет може переносити дані від клієнта до сервера. Після завершення цих операцій клієнт перейде у стан ESTABLISHED.

Як тільки сервер отримає пакет відповіді від клієнта, він також перейде у стан ESTABLISHED.

Як видно з наведеного вище процесу, під час виконання тристороннього рукостискання третє рукостискання може передавати дані, але перші два – ні. Це питання, яке часто ставлять на співбесідах. Після завершення тристороннього рукостискання обидві сторони переходять у стан ВСТАНОВЛЕНО, що вказує на успішне встановлення з'єднання, і в цей момент клієнт і сервер можуть почати надсилати дані один одному.

Чому три рукостискання? Не двічі, а чотири рази?
Поширена відповідь: «Тому що тристороннє рукостискання гарантує можливість отримання та надсилання». Ця відповідь правильна, але це лише поверхнева причина, яка не висуває головної. Далі я проаналізую причини потрійного рукостискання з трьох аспектів, щоб поглибити наше розуміння цього питання.

Тристороннє рукостискання може ефективно уникнути ініціалізації історично повторюваних з'єднань (основна причина)
Тристороннє рукостискання гарантує, що обидві сторони отримали надійний початковий порядковий номер.
Тристороннє рукостискання дозволяє уникнути марнування ресурсів.

Причина 1: Уникайте історичних дублікатів об'єднань
Коротко кажучи, основною причиною використання тристороннього рукостискання є уникнення плутанини, спричиненої старою дублікатною ініціалізацією з'єднання. У складному мережевому середовищі передача пакетів даних не завжди надсилається до хоста призначення відповідно до заданого часу, і старі пакети даних можуть надходити до хоста призначення першими через перевантаження мережі та інші причини. Щоб уникнути цього, TCP використовує тристороннє рукостискання для встановлення з'єднання.

тристороннє рукостискання дозволяє уникнути дублікатів з'єднань у минулому

Коли клієнт послідовно надсилає кілька пакетів встановлення SYN-з'єднання, у таких ситуаціях, як перевантаження мережі, може статися таке:

1. Старі SYN-пакети надходять на сервер раніше за найновіші SYN-пакети.
2. Сервер відповість клієнту пакетом SYN + ACK після отримання старого пакета SYN.
3. Коли клієнт отримує пакет SYN + ACK, він визначає, що з'єднання є історичним (термін дії порядкового номера минув або час очікування минув) відповідно до власного контексту, а потім надсилає пакет RST на сервер, щоб перервати з'єднання.

За допомогою двостороннього рукостискання неможливо визначити, чи є поточне з'єднання історичним. Тристороннє рукостискання дозволяє клієнту визначити, чи є поточне з'єднання історичним, на основі контексту, коли він буде готовий надіслати третій пакет:

1. Якщо це історичне з'єднання (термін дії порядкового номера минув або час очікування минув), пакет, надісланий третім рукостисканням, є RST-пакетом для переривання історичного з'єднання.
2. Якщо це не давнє з’єднання, пакет, надісланий втретє, є пакетом ACK, і дві сторони, що взаємодіють, успішно встановлюють з’єднання.

Отже, головною причиною використання TCP тристороннього рукостискання є ініціалізація з'єднання для запобігання історичним з'єднанням.

Причина 2: Синхронізувати початкові порядкові номери обох сторін
Обидві сторони протоколу TCP повинні підтримувати порядковий номер, що є ключовим фактором для забезпечення надійної передачі. Порядкові номери відіграють важливу роль у TCP-з'єднаннях. Вони виконують наступне:

Приймач може усунути дублікати даних та забезпечити їх точність.

Отримувач може отримувати пакети в порядку порядкового номера, щоб забезпечити цілісність даних.

● Порядковий номер може ідентифікувати пакет даних, отриманий іншою стороною, що забезпечує надійну передачу даних.

Таким чином, після встановлення TCP-з'єднання клієнт надсилає SYN-пакети з початковим порядковим номером і вимагає від сервера відповіді ACK-пакетом, який вказує на успішне отримання SYN-пакета клієнта. Потім сервер надсилає SYN-пакет з початковим порядковим номером клієнту та чекає на відповідь клієнта, раз і назавжди, щоб переконатися, що початкові порядкові номери надійно синхронізовані.

Синхронізуйте початкові серійні номери обох сторін

Хоча чотиристороннє рукостискання також можливе для надійної синхронізації початкових порядкових номерів обох сторін, другий і третій кроки можна об'єднати в один крок, що призведе до тристороннього рукостискання. Однак два рукостискання можуть гарантувати лише те, що початковий порядковий номер однієї сторони буде успішно отримано іншою стороною, але немає гарантії, що початковий порядковий номер обох сторін може бути підтверджено. Тому тристороннє рукостискання є найкращим вибором для забезпечення стабільності та надійності TCP-з'єднань.

Причина 3: Уникайте марнування ресурсів
Якщо є лише «подвійне рукостискання», коли SYN-запит клієнта заблоковано в мережі, клієнт не може отримати ACK-пакет, надісланий сервером, тому SYN буде надіслано повторно. Однак, оскільки третього рукостискання немає, сервер не може визначити, чи отримав клієнт підтвердження ACK для встановлення з'єднання. Тому сервер може проактивно встановлювати з'єднання лише після отримання кожного SYN-запиту. Це призводить до наступного:

Марна витрата ресурсів: Якщо SYN-запит клієнта блокується, що призводить до повторної передачі кількох SYN-пакетів, сервер встановить кілька надлишкових недійсних з'єднань після отримання запиту. Це призводить до непотрібної марної витрати ресурсів сервера.

Збереження повідомлень: Через відсутність третього рукостискання сервер не має можливості дізнатися, чи правильно отримав клієнт підтвердження ACK для встановлення з'єднання. Як наслідок, якщо повідомлення зависають у мережі, клієнт продовжуватиме надсилати SYN-запити знову і знову, змушуючи сервер постійно встановлювати нові з'єднання. Це збільшить перевантаження мережі та затримки, а також негативно вплине на загальну продуктивність мережі.

Уникайте марнування ресурсів

Тому, щоб забезпечити стабільність та надійність мережевого з'єднання, TCP використовує тристороннє рукостискання для встановлення з'єднання, щоб уникнути виникнення цих проблем.

Короткий зміст
TheМережевий пакетний брокерВстановлення TCP-з'єднання здійснюється за допомогою тристороннього рукостискання. Під час тристороннього рукостискання клієнт спочатку надсилає серверу пакет із прапорцем SYN, що вказує на бажання встановити з'єднання. Після отримання запиту від клієнта сервер відповідає клієнту пакетом із прапорцями SYN та ACK, що вказує на прийняття запиту на з'єднання, та надсилає свій власний початковий порядковий номер. Нарешті, клієнт відповідає серверу прапорцем ACK, що вказує на успішне встановлення з'єднання. Таким чином, дві сторони перебувають у стані ВСТАНОВЛЕНО та можуть почати надсилати дані одна одній.

Загалом, тристоронній процес встановлення TCP-з'єднання розроблений для забезпечення стабільності та надійності з'єднання, уникнення плутанини та марнування ресурсів через історичні з'єднання, а також для забезпечення можливості обох сторін отримувати та надсилати дані.


Час публікації: 08 січня 2025 р.