Тристоронній посібник TCP працює так:
Client ------SYN-----> Server
Client <---ACK/SYN---- Server
Client ------ACK-----> Server
Чому б не просто це?
Client ------SYN-----> Server
Client <-----ACK------ Server
Тристоронній посібник TCP працює так:
Client ------SYN-----> Server
Client <---ACK/SYN---- Server
Client ------ACK-----> Server
Чому б не просто це?
Client ------SYN-----> Server
Client <-----ACK------ Server
Відповіді:
Розбийте рукостискання на те, що це насправді робиться.
У TCP дві сторони відстежують, що вони надіслали, використовуючи номер послідовності. Ефективно, це в кінцевому підсумку - кількість поточних байтів, що надсилаються. Приймаюча сторона може використовувати порядковий номер оратора, який підтверджує те, що він отримав.
Але порядковий номер не починається з 0. Він починається з ISN (Initial Sequence Number), що є випадково вибраним значенням. А оскільки TCP - це двосторонній зв'язок, обидві сторони можуть "говорити", і тому обидві повинні випадковим чином генерувати ISN як свій стартовий номер послідовності. Що в свою чергу означає, що обидві сторони повинні повідомити іншу сторону про свій початковий ISN.
Отже, ви закінчите цю послідовність подій для початку розмови TCP між Алісою та Боб:
Alice ---> Bob SYNchronize with my Initial Sequence Number of X
Alice <--- Bob I received your syn, I ACKnowledge that I am ready for [X+1]
Alice <--- Bob SYNchronize with my Initial Sequence Number of Y
Alice ---> Bob I received your syn, I ACKnowledge that I am ready for [Y+1]
Зауважте, відбуваються чотири події:
Однак насправді дві середні події (№2 та №3) відбуваються в одному пакеті. Що робить пакет a SYN
або ACK
просто двійковим прапором, включеним або вимкненим всередині кожного заголовка TCP , тому нічого не заважає обом цим прапорам ввімкнутись в одному пакеті. Отже, тристороннє рукостискання закінчується таким:
Bob <--- Alice SYN
Bob ---> Alice SYN ACK
Bob <--- Alice ACK
Зауважте два екземпляри "SYN" та "ACK", по одному в кожному, в обох напрямках.
Отже, щоб повернутися до свого питання, чому б не просто скористатися двостороннім рукостисканням? Коротка відповідь полягає в тому, що двосторонній рукостискання дозволить лише одній стороні встановити ISN, а іншій стороні визнати це. Що означає, що лише одна сторона може надсилати дані.
Але TCP - це протокол двостороннього зв'язку, що означає, що будь-який кінець повинен мати можливість надійно надсилати дані. Обидві сторони повинні створити ІСН, і обидві сторони повинні визнати ІСН іншої.
Отже, насправді, це саме ваш опис двостороннього рукостискання, але в кожному напрямку . Отже, відбулися чотири події. І знову, середні два прапори трапляються в одному пакеті. Оскільки такі три пакети беруть участь у повному процесі ініціації TCP-з'єднання.
Трьохетапного необхідно тому , що обидві сторони повинні син chronize їх порядкові номери сегментів , які використовуються в процесі їх передачі. Для цього кожен з них надсилає (у свою чергу) відрізок SYN з порядковим номером, встановленим на випадкове значення n , яке потім ack відмічається іншою стороною через сегмент ACK з порядковим номером, встановленим n + 1 .
Eddie
коментаря російської до його відповіді
Для того, щоб з'єднання працювало, кожній стороні потрібно перевірити, чи може він пересилати пакети на іншу сторону. Єдиний спосіб бути впевненим, що ви отримали пакет на іншій стороні - це отримати від них пакет, який, за визначенням, не був би надісланий, якби пакет, який ви надіслали, отримав через . TCP по суті використовує для цього два типи повідомлень: SYN (для запиту доказу, що цей пакет пройшов) та ACK (який надсилається лише після того, як SYN проходить, щоб довести, що SYN пройшов). Насправді існує третій вид повідомлення, але ми до цього підемо миттєво.
Перед початком з'єднання жодна із сторін насправді нічого не знає про іншу. Клієнт відправляє на сервер пакет SYN, щоб вимагати підтвердження того, що його повідомлення можуть пройти . Це нікому не говорить нічого, але це перший крок рукостискання.
Якщо SYN проходить через сервер, сервер знає, що клієнт може надсилати йому пакети, тому що, ну, це просто сталося. Але це не доводить, що сервер може надсилати пакети назад: клієнти можуть надсилати SYN з безлічі причин . Таким чином, серверу потрібно відправити клієнту два повідомлення назад: ACK (щоб довести, що SYN пройшов) та SYN (вимагати власний ACK). TCP поєднує ці два повідомлення в одне-SYN-ACK повідомлення, якщо ви бажаєте - зменшити мережевий трафік. Це другий крок рукостискання.
Оскільки SYN-ACK є ACK, клієнт тепер точно знає, що може надсилати пакети на сервер. А оскільки SYN-ACK є SYN, він також знає, що сервер хоче підтвердити, що це повідомлення пройшло. Таким чином, він посилає назад ACK: на цей раз просто звичайний ACK, тому що він більше не потребує доказів того, що його пакети можуть пройти. Це останній крок рукостискання: клієнт тепер знає, що пакети можуть йти обома шляхами, і що сервер збирається це зрозуміти (адже він знає, що ACK пройде).
Як тільки цей ACK пройшов, тепер сервер знає, що він може надсилати пакети клієнту . Він також знає, що клієнт це знає, тому може почати надсилати дані відразу. Рукостискання завершено. У нас хороший канал.
Ну, строго кажучи, ми не можемо бути впевнені, що у нас хороший канал . Тільки тому, що така послідовність пакетів, які вони отримали, не гарантує суворої сили . Ми не можемо довести, що без надсилання нескінченної кількості SYN та ACK, і тоді нічого більше нічого не вдасться зробити, тож це насправді не практичний варіант. Але на практиці три кроки виявляються досить хорошими для більшості цілей .
Насправді тристоронній рукостискання - не єдиний засіб встановлення TCP-з'єднання. Дозволений також одночасний обмін SYN: http://www.tcpipguide.com/free/t_TCPConnectionEstablishmentProcessTheThreeWayHandsh-4.htm
Це можна було б розглянути як своєрідне подвійне двостороннє рукостискання.
TCP-з'єднання двостороннє. Це означає, що це насправді пара односторонніх зв’язків. Ініціатор посилає SYN, відповідач посилає ACK: починається одне симплексне з'єднання. "Потім" відповідь посилає SYN, ініціатор посилає ACK: починається ще одне симплексне з'єднання. Два симплексні з'єднання утворюють один двосторонній сеанс TCP, погодьтеся? Отже, логічно, є чотири кроки; але оскільки прапори SYN та ACK - це різні "поля" заголовка TCP, їх можна встановити одночасно - другий і третій кроки (з чотирьох) поєднуються, тому технічно існує три обміни пакетів. Кожне симплексне (напів-) з'єднання використовує двосторонній обмін, як ви запропонували.
Якщо Сервер і Клієнт хочуть створити з'єднання, їм потрібно підтвердити чотири речі:
Клієнт повинен підтвердити, що він може отримати пакет від Сервера
Клієнт повинен підтвердити річ: Сервер може отримувати пакет від Клієнта
Після цього Client ------SYN-----> Server
правило 1 підтверджується.
Після цього Client <---ACK/SYN---- Server
правила 2 і 3 підтверджуються.
Отже, для підтвердження правила 4 потрібен третій пакет.
Це зовсім не обов’язково. Очевидно, що для короткого повідомлення сервер повинен вимагати лише один пакет, який включає в себе повідомлення "старт +", і один пакет назад, що підтверджує його.
Попередні відповіді просто описують систему, не обговорюючи необхідності випадкових порядкових чисел тощо. Первісне питання стосувалося самої конструкції TCP - очевидно, якщо ви використовуєте протокол TCP, тоді вам потрібно три повідомлення, тому що це протокол. Але чому в першу чергу був розроблений TCP?
Я вважаю, що початковою ідеєю було те, що між клієнтами та серверами не було різниці. Обидва знали порти інших у двосторонній спосіб, і будь-хто міг розпочати розмову. А для цього потрібні Syns тощо.
Але це, звичайно, не так, як це використовується сьогодні. Сервер слухає добре відомий порт і робить і "приймає", номер порту клієнта є ефемерним. Я навіть не думаю, що сервер, який очікує на "прийняти", не може надіслати запит іншому на той же номер клієнтського порту в звичайних операційних системах.
(Зауважте, що мова йде про двонаправлене ініціювання з'єднання, яке ніколи не робиться сьогодні. Це зовсім відрізняється від надсилання двонаправлених повідомлень вниз після встановлення з'єднання.)
Щоб подолати неефективність TCP, ми використовуємо такі протоколи, як HTTP 1.1, які можуть повторно використовувати одне і те ж з'єднання для декількох запитів, і, таким чином, уникати рукостискання TCP, що в першу чергу не було необхідним.
Але Http 1.1 порівняно новий. І SSL / TLS потребував способу повторного використання сеансу з самого початку через вартість алгоритмів PKI. Таким чином, цей протокол включає власний механізм повторного використання сеансу, який працює над Http 1.1, який працює поверх TCP.
Такий шлях із програмним забезпеченням. Випади каламуті, які в поєднанні дають прийнятний результат.
Прочитавши відповідь Едді (прийнято як правильну), все ще виникає питання, чому 1-й хост не може призначити обидва ISN випадковими числами, а другий просто прийняти його. Справжня причина використання тристороннього рукостискання - уникати напівз’єднань . Половина сценарію підключення в двосторонньому рукостисканні:
1) Клієнт --- SYN -> Сервер
2) Клієнт передумав і більше не хоче підключатися
3) Клієнт <-X-ACK-- Сервер // ACK втрачено
Сервер не бачить обуреного SYN, тому він вважає, що клієнт отримав свій ACK і з'єднання встановлено. В результаті сервер має з'єднання, яке ніколи не буде закритим