Зачем нам нужно 3-стороннее рукопожатие? Почему не просто 2-way?

Трехстороннее рукопожатие TCP работает следующим образом:

Client ------SYN-----> Server
Client <---ACK/SYN---- Server
Client ------ACK-----> Server

Почему не только это?

Client ------SYN-----> Server
Client <-----ACK------ Server
tcp
101 голос | спросил smwikipedia 4 32015vEurope/Moscow11bEurope/MoscowWed, 04 Nov 2015 17:36:05 +0300 2015, 17:36:05

7 ответов


136

Разбейте рукопожатие на то, что он действительно делает.

В 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]

Обратите внимание, что происходят четыре события:

  1. Алиса выбирает ISN и SYNchronizes с Бобом.
  2. Боб ACKnowledges ISN.
  3. Боб выбирает ISN и SYNchronizes с Алисой.
  4. Alice ACKnowledges ISN.

В действительности, однако, средние два события (# 2 и # 3) происходят в одном пакете. Что делает пакет a SYN или ACK - это просто двоичный флаг, который включен или выключен внутри каждого TCP , поэтому нет ничего, что предотвращало бы включение обоих этих флагов в один и тот же пакет. Таким образом, трехстороннее рукопожатие заканчивается:

Bob <--- Alice         SYN
Bob ---> Alice     SYN ACK 
Bob <--- Alice     ACK     

Обратите внимание на два экземпляра «SYN» и «ACK», по одному в каждом из них.


Итак, чтобы вернуться к вашему вопросу, почему бы просто не использовать двухстороннее рукопожатие? Короткий ответ заключается в том, что двухстороннее рукопожатие позволит только одной стороне создать ISN, а другая сторона признает это. Это означает, что только одна сторона может отправлять данные.

Но TCP - это двунаправленный протокол связи, который означает, что любой конец должен иметь возможность надежно отправлять данные. Обеим сторонам необходимо создать ISN, и обе стороны должны признать ISN другого.

Таким образом, у вас есть именно ваше описание двустороннего рукопожатия, но в каждом направлении . Следовательно, происходят четыре события. И снова, два средних флажка происходят в одном пакете. Поскольку такие три пакета участвуют в полном запуске процесса TCP-соединения.

ответил Eddie 4 32015vEurope/Moscow11bEurope/MoscowWed, 04 Nov 2015 19:56:45 +0300 2015, 19:56:45
20

Трехстороннее рукопожатие необходимо, потому что обеим сторонам необходимо syn хронизировать их порядковые номера сегментов, используемые во время их передачи. Для этого каждый из них отправляет (в свою очередь) сегмент SYN с порядковым номером, установленным на случайное значение n , которое затем является ack , устаревшим другой стороной через ACK с порядковым номером, установленным на n + 1 .

ответил dr01 4 32015vEurope/Moscow11bEurope/MoscowWed, 04 Nov 2015 18:05:30 +0300 2015, 18:05:30
12

Для того, чтобы соединение работало, каждая сторона должна проверить, может ли он отправлять пакеты с другой стороны. Единственный способ убедиться, что вы получили пакет с другой стороны, - это получить от них пакет, который по определению не был бы отправлен, если только полученный вами пакет не прошел через . 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, и тогда ничего больше не будет сделано, так что это не практический вариант. Но на практике три шага оказываются достаточно хорошими для большинства целей .

ответил The Spooniest 5 42015vEurope/Moscow11bEurope/MoscowThu, 05 Nov 2015 17:44:54 +0300 2015, 17:44:54
7

Собственно, трехстороннее рукопожатие не является единственным средством установления TCP-соединения. Также допускается одновременный обмен SYN: http://www.tcpipguide.com/free/t_TCPConnectionEstablishmentProcessTheThreeWayHandsh- 4.htm

Это можно рассматривать как своеобразное двухстороннее рукопожатие.

ответил Lexelby 5 42015vEurope/Moscow11bEurope/MoscowThu, 05 Nov 2015 04:02:48 +0300 2015, 04:02:48
4

TCP-соединение двунаправлено. Это означает, что на самом деле это пара однонаправленных соединений. Инициатор отправляет SYN, ответчик отправляет ACK: начинается одно симплексное соединение. «Затем» ответчик отправляет SYN, инициатор отправляет ACK: начинается другое соединение симплекс. Два симплексных соединения образуют один дуплексный сеанс TCP, согласны? Таким образом, логически существует четыре этапа; но поскольку флаги SYN и ACK представляют собой разные «поля» заголовка TCP, они могут быть установлены одновременно - второй и третий шаги (из четырех) объединены, поэтому технически есть три обмена пакетами. В каждом симплексном (полу) соединении используется двухсторонний обмен, как вы предложили.

ответил Sergio 5 42015vEurope/Moscow11bEurope/MoscowThu, 05 Nov 2015 11:15:32 +0300 2015, 11:15:32
1

После прочтения ответа Эдди (принятого как правильно), все еще возникает вопрос, почему 1-й хост не может назначить оба ISN со случайными числами, а второй просто принять его. Настоящая причина использования трехстороннего рукопожатия заключается в том, чтобы избежать полуподключения . Половинный сценарий подключения в двухстороннем рукопожатии:
1) Клиент --- SYN -> Сервер
2) Клиент меняет свое мнение и больше не хочет подключаться 3) Клиент <-X-ACK-- Сервер //ACK был потерян
Сервер не видит resent SYN, поэтому он считает, что клиент получил свой ACK и соединение установлено. В результате сервер имеет соединение, которое никогда не будет закрыто

ответил Sanzhar Yeleuov 15 Maypm18 2018, 12:33:07
0

Это совсем не обязательно. Очевидно, что короткое сообщение должно требовать только один пакет для сервера, который включает в себя сообщение «начало +», и один пакет обратно подтверждает его.

Предыдущие ответы просто описывают систему, не обсуждая в первую очередь необходимость случайных порядковых номеров и т. д. Первоначальный вопрос касался дизайна самого TCP: очевидно, если вы используете протокол TCP, вам понадобятся три сообщения, потому что это протокол. Но почему именно TCP был спроектирован именно так?

Я считаю, что первоначальная идея заключалась в том, что между клиентами и серверами не было различий. Оба знали порты другого в двунаправленном порядке, и либо могли начать разговор. И это требовало Syns и т. Д.

Но это, конечно, не так, как сегодня используется. Сервер прослушивается на хорошо известном порту и выполняет и «принимает», номер порта клиента является эфемерным. Я даже не думаю, что сервер, ожидающий «принятия», отправит запрос другому на номер тот же клиентский порт в обычных операционных системах.

(Обратите внимание, что речь идет о двунаправленном инициировании соединения, которое никогда не выполняется сегодня. Это сильно отличается от отправки двунаправленных сообщений по соединению после его установки.)

Чтобы обойти неэффективность TCP, мы используем протоколы, такие как HTTP 1.1, которые могут повторно использовать одно и то же соединение для нескольких запросов и, таким образом, избегать рукопожатия TCP, которое не было необходимо в первую очередь.

Но Http 1.1 является относительно новым. И SSL /TLS нужен способ повторного использования сеанса с самого начала из-за стоимости алгоритмов PKI. Таким образом, этот протокол включает в себя собственный механизм повторного использования сеанса, который выполняется поверх Http 1.1, который работает поверх TCP.

Таков способ использования программного обеспечения. Выдумки на кломах, которые при объединении дают приемлемый результат.

ответил Tuntable 23 Mayam16 2016, 04:58:43

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132