Настройка TCP-соединения
Когда мы просматриваем веб-страницы, отправляем электронное письмо или играем в онлайн-игру, мы часто не задумываемся о сложном сетевом соединении, которое за этим стоит. Однако именно эти, казалось бы, незначительные шаги обеспечивают стабильную связь между нами и сервером. Один из важнейших этапов — установка TCP-соединения, в основе которого лежит трёхстороннее рукопожатие.
В этой статье подробно рассматриваются принцип, процесс и важность трёхстороннего рукопожатия. Мы шаг за шагом объясним, зачем нужно трёхстороннее рукопожатие, как оно обеспечивает стабильность и надёжность соединения и насколько оно важно для передачи данных. Более глубокое понимание трёхстороннего рукопожатия позволит нам лучше понять базовые механизмы сетевого взаимодействия и получить более чёткое представление о надёжности TCP-соединений.
Процесс трехстороннего рукопожатия TCP и переходы состояний
TCP — это транспортный протокол с установлением соединения, требующий установления соединения перед передачей данных. Процесс установления соединения осуществляется посредством трёхстороннего рукопожатия.
Давайте подробнее рассмотрим TCP-пакеты, отправляемые в каждом соединении.
Изначально и клиент, и сервер находятся в состоянии ЗАКРЫТО. Сначала сервер активно прослушивает порт и находится в состоянии LISTEN, что означает, что сервер должен быть запущен. Затем клиент готов начать доступ к веб-странице. Ему необходимо установить соединение с сервером. Формат первого пакета соединения следующий:
Когда клиент инициирует соединение, он генерирует случайный начальный порядковый номер (client_isn) и помещает его в поле «Порядковый номер» заголовка TCP. Одновременно клиент устанавливает флаг SYN в положение 1, указывая, что исходящий пакет является SYN-пакетом. Клиент подтверждает своё намерение установить соединение с сервером, отправляя ему первый SYN-пакет. Этот пакет не содержит данных прикладного уровня (то есть отправленных данных). В этот момент статус клиента помечается как SYN-SENT.
Когда сервер получает SYN-пакет от клиента, он случайным образом инициализирует свой серийный номер (server_isn) и помещает его в поле «Серийный номер» TCP-заголовка. Затем сервер вводит client_isn + 1 в поле «Номер подтверждения» и устанавливает биты SYN и ACK в 1. Наконец, сервер отправляет клиенту пакет, не содержащий данных прикладного уровня (и данных для отправки сервером). В этот момент сервер находится в состоянии SYN-RCVD.
После получения пакета от сервера клиенту необходимо выполнить следующие оптимизации для ответа на последний ответный пакет: во-первых, клиент устанавливает бит ACK в заголовке TCP ответного пакета в 1; во-вторых, клиент вводит значение server_isn + 1 в поле «Подтверждение номера ответа»; наконец, клиент отправляет пакет серверу. Этот пакет может переносить данные от клиента к серверу. После завершения этих операций клиент переходит в состояние ESTABLISHED.
Как только сервер получает ответный пакет от клиента, он также переходит в состояние 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, указывающий на успешное установление соединения. Таким образом, обе стороны находятся в состоянии ESTABLISHED и могут начать обмен данными.
В целом, процесс трехстороннего рукопожатия для установления TCP-соединения призван обеспечить стабильность и надежность соединения, избежать путаницы и траты ресурсов на предыдущие соединения, а также гарантировать, что обе стороны смогут получать и отправлять данные.
Время публикации: 08 января 2025 г.






