Небольшая реклама от моего паблика "Кэш YongHao для написания вещей", я все же надеюсь, что то, что я пишу, будет прочитано 🙊
Поделитесь своими мыслями
Непонимание и неправильная аналогия трехэтапного рукопожатия (интерпретация RFC)
Трехстороннее рукопожатие о TCP — почти частый вопрос на собеседованиях с выпускниками, но в Интернете все еще много ошибок.Почему TCP — это трехстороннее рукопожатие, а не два или четыре?Популярный ответ выше является примером, первая аналогия с 3,6 тыс. голосов неверна:
三次握手:
“喂,你听得到吗?”
“我听得到呀,你听得到我吗?”
“我能听到你,今天 balabala……”
Также эта 107-кратно одобренная аналогия неверна:
握手和敬军礼一样,源自「敌我双方互相确认对方手里没有武器、无恶意」的仪式。(虽然双方互相请求确认需要四步,但由于中间的确认和请求是由同一个人执行的,所以合并成了一步)
正恩伸出手说:你看,我手里没有武器。(SYN)
朗普看了看说:嗯,确实没有。(ACK)
于是也伸出手说:你看,我手里也没有武器。(SYN)
正恩看了看说:嗯,看来你确实有诚意。(ACK)
Эти две аналогии являются ошибками, которые считаются само собой разумеющимися, и почему они ошибочны, я думаю, вы поймете, прочитав полный текст.
Другой заключается в том, что в четвертом издании «Компьютерной сети» Се Сижэня цель «трехстороннего рукопожатия» состоит в том, чтобы «предотвратить повторную внезапную передачу на сервер недействительного сегмента запроса на подключение, что приведет к ошибкам». считать причиной, а не сущностью.
Пример в издании «Компьютерная сеть» Се Сирена выглядит следующим образом: «неверный сегмент запроса на соединение» генерируется в такой ситуации: первый сегмент запроса на соединение, отправленный клиентом, не потерян, но в узле сети A был застрял на долгое время, так что он задерживается до определенного времени после разрыва соединения до достижения сервера. Первоначально это был давно несуществующий сегмент. Однако после того, как сервер получает недопустимый сегмент запроса на подключение, он ошибочно считает, что это новый запрос на подключение, отправленный клиентом снова. Таким образом, он отправляет сегмент подтверждения клиенту и соглашается установить соединение. Предполагая, что «трехстороннее рукопожатие» не используется, новое соединение устанавливается до тех пор, пока сервер выдает подтверждение. Поскольку клиент сейчас не выдал запрос на установление соединения, он проигнорирует подтверждение сервера и не отправит данные на сервер. Но сервер считает, что установлено новое транспортное соединение и ждет, пока клиент отправит данные. Таким образом, многие ресурсы сервера тратятся зря. Подход «трехстороннего рукопожатия» может предотвратить возникновение описанного выше явления. Например, в данном случае клиент не будет выдавать подтверждение на подтверждение сервера. Поскольку сервер не получает подтверждения, он знает, что клиент не просил установить соединение. "
если ты внимательно читаешьRFC793, который является протоколом RFC TCP, вы обнаружите, что в нем говорится о том, почему трехстороннее рукопожатие необходимо — TCP нуждается в порядковом номере seq для надежной повторной передачи или приема и позволяет избежать мультиплексирования соединения. поэтому требуется трехстороннее рукопожатие для согласования определения ISN (начального последовательного порядкового номера) обеих сторон.
Подробные инструкции по интерпретации RFC приведены ниже: (Пакеты данных называются сегментами, которые обычно называются пакетами в Китае)
Первое, что нам нужно знать, это то, что надежное соединение TCP достигается с помощью seq (порядковые номера).
A fundamental notion in the design is that every octet of data sent over a TCP connection has a sequence number. Since every octet is sequenced, each of them can be acknowledged.
The acknowledgment mechanism employed is cumulative so that an acknowledgment of sequence number X indicates that all octets up to but not including X have been received.
Базовая настройка архитектуры TCP заключается в том, что каждый пакет, отправляемый через TCP-соединение, имеет порядковый номер. А поскольку каждый пакет имеет серийный номер, можно подтвердить, что эти пакеты получены.
Механизм подтверждения является кумулятивным, поэтому подтверждение для порядкового номера X означает, что пакеты до X включительно с порядковым номером X были подтверждены как полученные.
The protocol places no restriction on a particular connection being used over and over again.
The problem that arises from this is -- "how does the TCP identify duplicate segments from previous incarnations of the connection?" This problem becomes apparent if the connection is being opened and closed in quick succession, or if the connection breaks with loss of memory and is then reestablished.
Протокол TCP не ограничивает повторное использование определенного соединения (одного и того же сокета на обоих концах).
Итак, возникает проблема: после того, как соединение внезапно разрывается и снова подключается, как TCP идентифицирует пакеты, повторно переданные по старому каналу? - Для этого требуется уникальный механизм ISN (начальный серийный номер).
When new connections are created, an initial sequence number (ISN) generator is employed which selects a new 32 bit ISN. The generator is bound to a (possibly fictitious) 32 bit clock whose low order bit is incremented roughly every 4 microseconds. Thus, the ISN cycles approximately every 4.55 hours. Since we assume that segments will stay in the network no more than the Maximum Segment Lifetime (MSL) and that the MSL is less than 4.55 hours we can reasonably assume that ISN's will be unique.
Когда новое соединение установлено,初始序列号( initial sequence number ISN)生成器
Генерируется новый 32-битный ISN.
Этот генератор будет использовать 32-битные часы, примерно4µs
Увеличивается один раз, поэтому ISN зацикливается каждые 4,55 часа.
(2^32
битовый счетчик, требуется2^32*4 µs
Для самоувеличения разделите его на общее количество мкс за 1 час, чтобы рассчитать2^32*4 /(1*60*60*1000*1000)=4.772185884
)
И сегмент в сети не будет длиннее максимального времени жизни сегмента (Максимальное время жизни сегмента (MSL), использование по умолчанию 2 минуты), MSL короче 4,55 часов, поэтому можно считать, что ISN будет уникальным.
И отправитель, и получатель будут иметь свои собственные ISN (X и Y в следующем примере) для связи друг с другом.Конкретное описание выглядит следующим образом:
- A --> B SYN my sequence number is X
- A <-- B ACK your sequence number is X
- A <-- B SYN my sequence number is Y
- A --> B ACK your sequence number is Y
2 и 3 оба отправляются от B к A, поэтому их можно объединить вместе, таким образом становясьthree way (or three message) handshake
(На самом деле оно переводится как трехэтапное рукопожатие, или точнее трехстороннее коммуникативное рукопожатие)
Следовательно, можно сделать вывод, что трехстороннее рукопожатие необходимо:
A three way handshake is necessary because sequence numbers are not tied to a global clock in the network, and TCPs may have different mechanisms for picking the ISN's. The receiver of the first SYN has no way of knowing whether the segment was an old delayed one or not, unless it remembers the last sequence number used on the connection (which is not always possible), and so it must ask the sender to verify this SYN. The three way handshake and the advantages of a clock-driven scheme are discussed in [3].
Трехстороннее рукопожатие необходимо, потому что порядковые номера (порядковые номера) не привязаны к глобальным часам всей сети (все используют одни часы, чтобы определить, задержан ли пакет), и TCP могут иметь разные механизмы для выбора ISN ( начальный порядковый номер).
Когда получатель получает первый SYN, нет никакой возможности узнать, задерживался ли SYN на долгое время, если только у него нет способа запомнить последние полученные порядковые номера в этом соединении (однако это не всегда возможно).
Смысл этого предложения таков: грядет последовательность, которая отличается от последовательности, которую я сейчас помню.Как я узнаю, задерживается ли она предыдущей статьей или задерживается предыдущей статьей?
Следовательно, получатель должен подтвердить SYN у отправителя.
Если предположить, что SEQ в SYN не подтвержден, то только:
- A --> B SYN my sequence number is X
- A <-- B ACK your sequence number is X SYN my sequence number is Y
Только B подтверждает получение SEQ от A, и A не может подтвердить получение B. То есть только пакеты, отправленные A к B, являются надежными, а пакеты, отправленные B к A, — нет, поэтому это ненадежное соединение. В этом случае, если A нужно только отправить B, а B не нужно отвечать, то трехэтапное рукопожатие можно опустить.
Подробный процесс трехстороннего рукопожатия
TCP A TCP B
1. CLOSED LISTEN
2. SYN-SENT --> <SEQ=100><CTL=SYN> --> SYN-RECEIVED
3. ESTABLISHED <-- <SEQ=300><ACK=101><CTL=SYN,ACK> <-- SYN-RECEIVED
4. ESTABLISHED --> <SEQ=101><ACK=301><CTL=ACK> --> ESTABLISHED
5. ESTABLISHED --> <SEQ=101><ACK=301><CTL=ACK><DATA> --> ESTABLISHED
Basic 3-Way Handshake for Connection Synchronization
Figure 7.
на картинке выше
- Во второй строке A отправляет SEQ 100, а бит флага равен SYN;
- В третьей строке B отправляет обратно ACK 101 и SEQ 300, а флаги — SYN и ACK (объединяются два процесса). Обратите внимание, что ACK 101 означает, что B ожидает получить сегменты данных, начиная с порядкового номера 101.
- В четвертой строке A возвращает пустые данные, SEQ 101, ACK 301 и флаг ACK. В этот момент было подтверждено получение начальных номеров SEQ (то есть ISN) 100 и 300 обеих сторон.
- В пятой строке пакет данных официально отправлен.Обратите внимание, что ACK по-прежнему 301 в четвертой строке, потому что нет SYN, который требует ACK (четвертая строка была подтверждена).