В первые годы существования Интернета Интернет-протокол (IP) был единственным протоколом, который люди использовали для подключения к Интернету. Проблема с IP заключалась в том, что вы могли отправить сообщение и не быть уверенным, получит его получатель или нет. По этой причине был установлен TCP/IP.
TCP/IP гарантирует, что все отправляемые вами данные дойдут до получателя. Он делает это, предоставляя клиенту и серверу безопасное соединение перед отправкой данных. Это безопасное соединение устанавливается с помощью процесса, известного как трехстороннее рукопожатие, также известное как рукопожатие TCP/IP.
Что такое трехстороннее рукопожатие?
Трехстороннее рукопожатие (рукопожатие TCP/IP) — это первые три взаимодействия между клиентом и сервером, пытающимся установить TCP-соединение. Эти начальные взаимодействия необходимы для создания безопасного соединения. На этом этапе и клиент, и сервер согласуют параметры, которые они будут использовать для проверки входящих и исходящих пакетов данных. Эти параметры будут представлены в виде сегментов TCP.
Что такое TCP-сегмент?
В соединении TCP/IP все отправляемые данные должны быть разделены и структурированы в так называемых сегментах TCP. Эти сегменты содержат такую информацию, как IP-адреса, порты, флаговые биты, порядковые номера, номера подтверждений и дополнительные данные или полезную нагрузку.
Первые три взаимодействия (трехстороннее рукопожатие) будут содержать только заголовки сегментов TCP без полезной нагрузки или прикрепленных данных. Вот пример сегмента TCP
Обратите внимание, что приведенная выше иллюстрация относится только к протоколу TCP. Для полного сегмента TCP/IP требуются оба IP-адреса от отправителя и получателя поверх сегмента TCP выше.
Всякий раз, когда вы отправляете посылку человеку, служба доставки требует от вас заполнить информационную форму, а затем прикрепить ее к посылке перед отправкой. Точно так же TCP требует, чтобы отправитель присоединил заголовок сегмента (информационную форму) к данным (пакету), прежде чем он начнет отправлять сегмент (посылку) получателю.
Всякий раз, когда клиент связывается с сервером, обе стороны должны форматировать свои взаимодействия в форме сегмента TCP. Сегмент TCP состоит из заголовка сегмента TCP, прикрепленного к данным, которые вы пытаетесь отправить. Отправитель должен будет заполнить информацию, которую требует глава сегмента.
Для трехстороннего рукопожатия отправителю необходимо заполнить следующее:
- Исходный порт: Идентифицирует порт отправителя
- Порт назначения: Идентифицирует порт получателя
- Последовательность чисел: Указывает последовательность сегментов
- Номер подтверждения: Означает, что сегмент был подтвержден путем добавления единицы к заданному порядковому номеру.
Помимо заполнения полей заголовка сегмента, отправитель также должен выбрать флаговый бит. Всего имеется шесть флаговых битов, но для трехэтапного рукопожатия вам понадобятся только следующие два:
- СИН: Дает порядковый номер. Этот порядковый номер будет использоваться для подсчета последовательности всех входящих сегментов для остальной части взаимодействия.
- ПОДТВЕРЖДЕНИЕ: Указывает, что получатель номера SYN принимает запрос на соединение, добавляя единицу (1) к указанному номеру SYN.
Теперь, когда вы знаете, что такое сегмент TCP, давайте посмотрим, как он используется в трехстороннем рукопожатии.
Как работает трехстороннее рукопожатие
Трехстороннее рукопожатие устанавливается, когда и клиент, и хост обмениваются информацией и подтверждают порядковые номера друг друга. Как следует из названия, трехстороннее рукопожатие выполняется в три этапа.
Сначала клиент отправляет чистый сегмент SYN, указывающий, что он хочет установить соединение. Во-вторых, сервер отвечает сегментом SYN-ACK, что означает, что он подтвердил запрос и отправляет свой собственный номер SYN для подтверждения клиентом. В-третьих, клиент отправляет сегмент ACK на сервер, чтобы уведомить его о том, что номер SYN сервера был подтвержден и будет использоваться для дальнейшего соединения.
Трехстороннее рукопожатие будет выглядеть примерно так:
Давайте разберем его и посмотрим на сегменты, чтобы вы знали, что именно происходит, когда клиент и сервер обмениваются и подтверждают порядковые номера.
Шаг 1: Клиент отправляет сегмент SYN
Клиент отправляет соединение запроса, отправляя сегмент SYN на сервер. Клиент использует IP-адрес клиента, чтобы найти сервер и отправить сегмент TCP.
Чтобы уменьшить сложность сегмента, давайте проигнорируем несколько полей сегмента и сосредоточимся на самом необходимом для трехэтапного рукопожатия. Это включает исходный порт, порт назначения, порядковый номер, номер подтверждения и тип используемого бита флага.
При этом сегмент SYN/запроса должен выглядеть так:
Порт клиента — это случайное число от 49152 до 65536. Этот диапазон портов является согласованным диапазоном, который общедоступные устройства могут динамически использовать для подключения к Интернету. Диапазоны портов от 1024 до 49151 являются частными. Они должны быть зарегистрированы организацией, чтобы использовать порт в указанном диапазоне. Номера портов ниже 1024 — это порты, зарезервированные для различных функций и интернет-протоколов, таких как FTP (порт 20), SMTP (порт 25), DNS (порт 53) и HTTP (порт 80).
В реальной жизни порядковый номер — это случайное число. Например, мы использовали 0000000000, чтобы упростить визуализацию.
Обратите внимание на порядковый номер по мере продвижения по шагам. В настоящее время это 000000000. В настоящее время нет номера подтверждения, так как нечего подтверждать.
Шаг 2: Сервер отвечает сегментом SYN-ACK
Как только сервер получит сегмент SYN, он ответит отправкой сегмента ACK, содержащего номер подтверждения. Номер подтверждения будет представлять собой порядковый номер клиента плюс один (1).
Посмотрите на исходный порт. Он показывает, что сегмент от порта 20, что указывает на то, что он пришел с сервера в качестве ответа.
Теперь посмотрите на номер подтверждения. Это 0000000001, то есть порядковый номер клиента (0000000000) плюс один (1). Так отслеживается сегмент. Допустим, клиент получил ответ сегмента ACK, в котором номер подтверждения равен 0000000002. Это укажет клиенту, что сегмент 0000000001 отсутствует и что клиенту придется подождать, пока он не появится. так что вы не столкнетесь с потерей пакетов.
Как видите, активируются два флаговых бита — SYN и ACK.
Помимо подтверждения порядкового номера клиента, сервер также отправит клиенту свой собственный порядковый номер для подтверждения порядкового номера сервера плюс один (1). В нашем примере мы использовали 1111111111 в качестве порядкового номера сервера. Опять же, в реальном мире это число случайное.
Обратите внимание, что порядковые номера клиента и сервера не обязательно должны совпадать. Пока обе стороны признают уникальный порядковый номер друг друга, соединение будет надежным.
Шаг 3: Клиент отвечает сегментом ACK
Наконец, клиент подтверждает порядковый номер сервера.
Последний сегмент — это сегмент ACK от клиента.
Как вы можете, клиент подтвердит порядковый номер сервера, ответив порядковым номером сервера (1111111111) плюс один (1), что равно 1111111112.
Клиент и сервер больше не будут отправлять порядковый номер, так как начало последовательности уже подтверждено. Однако обе стороны будут ожидать, что сегменты подтверждения будут продолжать порядковые номера плюс один (1) и количество байтов на протяжении всего взаимодействия. В этом случае клиент ожидает, что следующий ответ сервера будет иметь ACK 0000000002 (если нет прикрепленных данных).
После чего устанавливается трехстороннее рукопожатие!
Понимание того, как работают сетевые подключения
Теперь, когда вы узнали, как работает трехстороннее рукопожатие, вам также будет легче понять, как работает TCP после рукопожатия. Клиент и сервер начнут отправлять данные после установления рукопожатия. На этот раз будет использоваться полный формат сегмента, а также дополнительные данные или полезная нагрузка.
Данные обычно сегментируются/нарезаются на более мелкие части для облегчения передачи. Каждый сегмент данных имеет свой собственный заголовок сегмента, содержащий порядковый номер и номер подтверждения. Причина использования порядкового номера состоит в том, чтобы знать последовательность сегментов, когда они в конечном итоге будут собраны. Номера подтверждений предназначены для проверки отправителем того, что его сегмент был получен и что он соответствует последовательности входящих сегментов.
Подсчет порядкового номера и его проверка с помощью подтверждения — это то, как TCP может надежно передавать огромные блоки данных без каких-либо пропущенных пакетов данных.
И при этом у вас должно быть довольно хорошее представление о том, как работает TCP.