Дизайнер иллюстрирует процесс соединения TCP

Linux JavaScript TCP/IP

предисловие

Мы знаем, что уровень IP упаковывает сегмент tcp и переносит его с IP-адреса источника на IP-адрес получателя. сообщение об ошибке. В этом случае tcp обнаружит, что данные потеряны, и передаст их повторно.
В этой статье я хочу исследовать, как это делает протокол TCP.Как дизайнер, я не могу не скопировать свою старую работу и не нарисовать две картинки.

Различия IP, UDP, TCP

IP — это протокол сетевого уровня, TCP и UDP — протоколы транспортного уровня, и оба они основаны на протоколе IP для передачи данных. Далее мы анализируем их сходства и различия в нескольких важных первых частях.
В заголовках трех протоколов есть 16-битные контрольные суммы, но контрольные суммы в заголовках IP-протокола охватывают только заголовки IP, тогда как контрольные суммы в заголовках TCP и UDP содержат все данные, а это означает, что протокол IP не заботится о том, данные верны, в то время как TCP и UDP заботятся.
Самая важная часть IP-заголовка — это 32-битный IP-адрес источника и IP-адрес назначения. Другие заголовки работают с ним для беспрепятственной передачи данных с IP-адреса источника на IP-адрес назначения. TCP и UDP отвечают за маркировку соответствующих портов. разница между TCP и UDP в чем?
Давайте сначала посмотрим на UDP, у него всего 4 заголовка, первые два определяют порт, а последние два обеспечивают точность данных. IP-протокол передает данные на машину с IP-адресом назначения.UDP проверяет данные по длине и контрольной сумме в заголовке.Если проверка не удалась, протокол UDP напрямую отбрасывает данные, не отправляя сообщение на исходный IP-адрес и порт ., поэтому протокол UDP ориентирован на дейтаграммы.
Недостатком UDP является то, что мы не можем гарантировать, что другая сторона получит отправленные мной данные. Но его преимущества легко увидеть с первой части: он легкий и быстрый.
Посмотрите еще раз на TCP, очевидно, что он заботится не только о данных, но и о других вещах, самая важная из которых — надежность соединения. Ниже мы в основном увидим, что эти заголовки делают в процессе соединения и отключения TCP.
В заголовке TCP есть 6 флаговых битов, которые по умолчанию равны 0 и при необходимости устанавливаются в 1, и через них завершается запрос и ответ. Их соответствующие значения следующие:

URG: срочный указатель
ACK: номер подтверждения Действует
PSH: отправьте данные в процесс-получатель как можно быстрее.
RST: восстановить соединение
SYN: порядковый номер синхронизации используется для инициирования соединения.
FIN: отправитель завершает задачу отправки

Процесс подключения и статус

Я нарисовал диаграмму, чтобы описать процесс и изменения состояния TCP-соединения:

Общая ситуация (фиолетовые и зеленые части на картинке)

трехстороннее рукопожатие
Первая фиолетовая стрелка (сверху вниз):

По умолчанию сервер находится в LISTEN Статус прослушивает порт. Когда клиент хочет подключиться к этому порту, клиент сначала случайным образом генерирует начальный серийный номер (j на рисунке), 32-битный серийный номер в заголовке (далее серийный номер) становится j+1, и SYN в заголовке Установить от 0 до 1. После того, как клиент отправил сегмент TCP с этими заголовками, состояние становится SYN_SENT .

Первая зеленая стрелка:

Когда сервер получает первый TCP-сегмент клиента с SYN, клиент отправляется LISTEN статус становится SYN_RCVD состояние, и отправьте часть данных, в которой первый ACK установлен в 1, а 32-битный номер подтверждения (далее — номер подтверждения) представляет собой порядковый номер (j)+1, отправленный клиентом, который означает, что данные клиента получены. При этом SYN также устанавливается в 1, а серийный номер — k. Смысл в том, что я тоже хочу соединиться с тобой.

Вторая фиолетовая стрелка:

Когда клиент получает ACK от сервера, статус меняется на ESTABLISLISHED , отправить данные одновременно, первый ACK равен k+1, что означает, что данные сервера получены. В это время клиент установил соединение, и то, сможет ли сервер установить соединение, зависит от того, сможет ли он получить данные с ACK, отправленным текущим клиентом. Если сервер его получает, его состояние также становится ESTABLISLISHED .
В этот момент соединение установлено и возможен обмен данными.

помахал четыре раза
Третья фиолетовая стрелка:

Независимо от особых обстоятельств, таких как сбой питания, сторона, которая активно завершает работу (клиент на рисунке, но не всегда), отправляет FIN+серийный номер m, и состояние изменяется на FIN_WAIT_1 .

Вторая зеленая стрелка:

Пассивно закрытая сторона (сервер на рисунке, но не всегда) получает статус и меняется на CLOSE_WAIT . В то же время немедленно отправляется номер подтверждения m+1, а заголовок ACK устанавливается равным 1. В это время состояние сервера меняется на LAST_ACK , это легко понять, это последнее подтверждение, после того, как клиент получает ACK, государственные изменения в FIN_WAIT_2 .

Третья зеленая стрелка:

сервер LAST_ACK После этого он может продолжить выполнение других операций, после завершения которых сервер также отправит FIN + серийный номер n.

Четвертая фиолетовая стрелка:

После получения клиентом FIN статус меняется на TIME_WAIT , Одновременная передача информации подтверждения ACK n + 1, сервер получает ACK, статус меняется на CLOSE .
В этот момент соединение разрывается.

Почему волна 4 вместо 3?

Есть проблема при вейве, почему нельзя отправить ACK и FIN вместе? Это вызвано полузакрытием TCP. TCP-соединения являются полнодуплексными (то есть данные могут передаваться в обоих направлениях одновременно), поэтому каждое направление необходимо закрывать отдельно.
Получение FIN означает только то, что другая сторона больше не будет отправлять мне данные, но TCP по-прежнему поддерживает меня для продолжения отправки данных другой стороне (конечно, в практических приложениях очень мало программ, которые это делают), если мы используйте Wireshark. Когда вы ждете, пока инструмент захватит сумку, часто видно, что волна всего 3 раза.

Что такое 2MSL рядом с TIME_WAIT?

       TIME_WAIT Это состояние также известно как состояние ожидания 2x MSL. MSL — это максимальное время жизни пакета TCP. Когда TCP активно закрывается и отправляет последний ACK (последняя фиолетовая линия в правом нижнем углу рисунка), он должен быть TIME_WAIT Состояние ожидает в два раза больше времени MSL, чтобы другая сторона не получила ACK, а затем повторно отправила FIN. Так что на один раз уходит в два раза больше времени.
По умолчанию операционная система выключается через 240 с (то есть в два раза дольше двух минут). TIME_WAIT соединение, порт будет занят до тех пор.
На сервере Linux вы можете изменить значение по умолчанию (в секундах), изменив файл /etc/sysctl.conf: net.ipv4.tcp_fin_timeout=30. Но это обычно также создает некоторые проблемы.

Открыть одновременно (фиолетовые и оранжевые части на картинке)

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

Закрыть одновременно (фиолетовые и оранжевые части на картинке)

Для удобства я нарисовал и открытые и закрытые одновременно, на самом деле открытое одновременно не обязательно может быть одновременно закрытым. Можно открывать и закрывать одновременно.

TCP-сервер обрабатывает номера портов

Давайте сначала вызовем команду natstat, чтобы увидеть сервер telnet. -a: показать все; -n: указать IP в десятичном формате с точками; -finet: показать только TCP и UDP. Во-первых, когда нет связи, это выглядит так:

Заголовки — это протокол, количество полученных запросов, количество отправленных запросов, локальный адрес, удаленный адрес и статус. Данные на рисунке показывают: текущий локальный порт 23 находится вLISTENСтатус, прослушивание запросов с любого IP. Давайте посмотрим на статус, когда приходит запрос:
Всего есть три состояния, и эти три состояния соответствуют трем процессам.LISTENГосударственный процесс всегда существует и принимает сегмент SYN. ​​Как только рукопожатие успешно, модуль TCP в системном ядре создаетESTABLISHEDсостояние процесса.

очередь запросов на входящее соединение

Если сервер получает большое количество запросов одновременно, и сервер в данный момент не способен их обрабатывать (или имеет более высокий приоритет процесса). TCP сначала кэширует запрос в очереди фиксированной длины (длина очереди обычно равна 5, что называется значением невыполненной работы).
Прикладной уровень будет продолжать потреблять очередь. При наличии отставания сервер перестанет получать пакеты SYN и не будет возвращать никаких сообщений. В это время клиент будет отображать тайм-аут.

Время подтверждения задержки

Обычно TCP не отправляет ACK сразу после получения данных, вместо этого он откладывает их отправку, так что ACK отправляется вместе с данными, которые необходимо отправить в этом направлении (явление, известное как совмещение данных). Большинство реализаций используют задержку 200 мс.
200 мс — максимальное время.Если всегда есть данные, ожидающие отправки, то время задержки подтверждения отсутствует.

Алгоритм Нэгла

Алгоритм Нэгла предназначен для решения задач малого сечения. Так называемый «малый сегмент» относится к блоку данных, размер которого меньше максимального размера MSS. Например, приложения, которые генерируют данные по одному байту за раз (например, интерактивный ввод), могут перегрузить сеть слишком большим количеством пакетов.
Основное определение алгоритма Нэгла состоит в том, что в любой момент времени может быть только один неподтвержденный сегмент. Правила следующие:

1. Если длина пакета достигает MSS, его отправка разрешается;
2. Если в нем есть FIN, то разрешена отправка;
3. Если установлена ​​опция TCP_NODELAY, разрешена отправка;
4. Когда опция TCP_CORK не установлена, если все исходящие пакеты подтверждены, их отправка разрешена;
5. Если вышеуказанные условия не выполняются, но происходит тайм-аут (обычно 200 мс), он будет отправлен немедленно.

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

Суммировать

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

использованная литература

  • "Подробное объяснение TCP/ip - Том 1"
  • "Графический TCP/IP"