1.5w слов + 24 картинки Live to Turn ПТС.

задняя часть внешний интерфейс
1.5w слов + 24 картинки Live to Turn ПТС.

TCP ориентирован на соединение单播протокола, в TCP нет такого поведения, как многоадресное и широковещательное, потому что IP-адреса отправителя и получателя могут быть четко определены в сегменте TCP.

Перед отправкой данных обе стороны, взаимодействующие друг с другом (т. е. отправитель и получатель), должны установить连接, после отправки данных обеим сторонам необходимо отключиться, то есть установить и разорвать TCP-соединение.

Установление и завершение TCP-соединений

Если вы читали статью о сетевом уровне, которую я написал ранее, вы должны знать, что существует четыре основных элемента TCP:IP-адрес отправителя, номер порта отправителя, IP-адрес получателя, номер порта получателя. И IP-адрес каждой стороны + номер порта можно рассматривать как套接字, сокет может быть однозначно идентифицирован. Розетка эквивалентна двери, и через эту дверь требуется передача данных.

Установление TCP-соединения -> завершение делится на три этапа

Основное внимание в нашем обсуждении ниже также уделяется этим трем уровням.

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

Установление TCP-соединения - трехстороннее рукопожатие

  1. Серверный процесс готов принимать TCP-соединения извне, обычно вызывая функции bind, listen и socket. Этот способ открытия считается被动打开(passive open). Затем серверный процесс находится вLISTENСтатус, ожидание запроса на подключение клиента.
  2. клиент черезconnectположить начало主动打开(active open), отправить запрос на подключение к серверу, бит синхронизации заголовка в запросе равен SYN = 1, и при этом выбирается начальная последовательность порядковых номеров, сокращенно seq = x. Сегмент SYN не может передавать данные и использует только порядковый номер. В этот момент клиент входитSYN-SENDусловие.
  3. После того, как сервер получает соединение от клиента, ему необходимо подтвердить сегмент клиента. В сегменте подтверждения установите биты SYN и ACK в 1. Номер подтверждения равен ack = x + 1, а также выбирает для себя начальный порядковый номер seq = y. Этот сегмент также не может передавать данные, но также использует порядковый номер. В этот момент TCP-сервер входитSYN-RECEIVED(同步收到)условие.
  4. После получения ответа от сервера клиенту также необходимо подтвердить соединение. ACK в подтверждающем соединении устанавливается равным 1, порядковый номер — seq = x + 1, а подтверждающий номер — ack = y + 1. TCP определяет, может ли этот сегмент нести данные или нет.Если он не несет данных, порядковый номер следующего сегмента данных по-прежнему будет seq = x + 1. В этот момент клиент входитESTABLISHED (已连接)условие
  5. После того, как сервер получает подтверждение от клиента, он также входитESTABLISHEDусловие.

Это типичный процесс трехэтапного рукопожатия, и установление TCP-соединения может быть завершено через три вышеуказанных сегмента. Цель трехэтапного рукопожатия состоит не только в том, чтобы сообщить взаимодействующим сторонам, что соединение устанавливается,Также можно использовать поле option в пакете данных для обмена некоторой специальной информацией и обмена начальным порядковым номером..

Как правило, сторона, отправившая SYN-сообщение первой, считается активно открывающей соединение, и эту сторону часто называют客户端. А получателя SYN обычно называют服务端, который используется для получения этого SYN и отправки следующего SYN, поэтому этот метод открытия является пассивным.

TCP требуется три сегмента для установления соединения и четыре сегмента для разрыва соединения.

Отключение TCP — четыре волны

После завершения передачи данных обе стороны связи могут разорвать соединение. После окончания передачи данных и клиентский хост, и серверный хост находятся в состоянии ESTABLISHED, а затем вступают в процесс освобождения соединения.

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

  1. Клиентское приложение отправляет сегмент сообщения, чтобы освободить соединение, прекращает отправку данных и активно закрывает TCP-соединение. Хост-клиент отправляет сегмент сообщения, чтобы разорвать соединение, первый бит FIN в сегменте сообщения равен 1, не содержит данных, а бит порядкового номера seq = u, в это время хост-клиент вводитFIN-WAIT-1(终止等待 1)сцена.

  2. После того, как хост-сервер получает сегмент сообщения, отправленный клиентом, он отправляет ответное сообщение с подтверждением, подтверждает, что ACK = 1 в ответном сообщении, и генерирует свой собственный бит порядкового номера seq = v, ack = u + 1, а затем хост сервера входитCLOSE-WAIT(关闭等待)условие.

  3. После того как хост-клиент получает ответ с подтверждением от хоста-сервера, он входит вFIN-WAIT-2(终止等待2)статус. Сегмент, ожидающий, пока клиент освободит соединение.

  4. В это время хост-сервер отправит сегмент отключения.В сегменте ACK = 1, порядковый номер seq = v, ack = u + 1. После отправки сообщения запроса на отключение хост-сервер попадет внутрьLAST-ACK(最后确认)сцена.

  5. После того, как клиент получает запрос на отключение от сервера, клиент должен ответить, и клиент отправляет отключенный сегмент.В сегменте ACK = 1, порядковый номер seq = u + 1, потому что клиент больше не отправляет данные после соединение разорвано, ack = v + 1, а затем введите вTIME-WAIT(时间等待)Статус, обратите внимание, что в настоящее время TCP-соединение не разорвано. Настройка, которая должна ждать некоторое время, т.е.2MSLПосле этого клиент войдетCLOSEDсостояние, время MSL называется最长报文段寿命(Maximum Segment Lifetime).

  6. После того, как сервер в основном получит подтверждение отключения от клиента, он перейдет в состояние ЗАКРЫТО. Поскольку сервер завершает соединение TCP раньше, чем клиент, и весь процесс отключения соединения должен отправить четыре сегмента сообщения, процесс разрыва соединения также называется четырьмя волнами.

Любая сторона TCP-соединения может инициировать операцию закрытия, но обычно операцию закрытия соединения инициирует клиент. Однако некоторые серверы, такие как веб-серверы, также инициируют операцию закрытия соединения после ответа на запрос. Протокол TCP указывает, что операция выключения инициируется отправкой сообщения FIN.

Подводя итог, можно сказать, что для установления TCP-соединения необходимы три сегмента, а для закрытия TCP-соединения необходимы четыре сегмента. Протокол TCP также поддерживает半开启(half-open)статус, хотя это бывает редко.

TCP полуоткрытый

TCP-соединение находится в полуоткрытом состоянии, потому что одна сторона соединения закрыла или разорвала TCP-соединение без уведомления другой стороны, то есть два человека общаются в WeChat, значит, вы не в сети, если вы этого не сделаете. скажи, я еще с тобой разговариваю. В этот момент соединение считается установленным.半开启условие. Это происходит, когда одна сторона в общении находится в ситуации, когда главный компьютер выходит из строя, вы ххх, мой компьютер умер, как я могу вам сказать? Пока сторона в полуподключенном состоянии не передает данные, невозможно обнаружить, что другой хост находится в автономном режиме.

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

ПТС полузакрыт

Поскольку TCP поддерживает полуоткрытые операции, мы можем представить, что TCP также поддерживает полузакрытые операции. Точно так же полузакрытие TCP не является обычным явлением. Полузакрытая операция TCP относится кЗакрыть только одно направление передачи потока данных. Комбинация двух операций полузакрытия закрывает все соединение. При нормальных обстоятельствах две взаимодействующие стороны завершат соединение, отправив сегменты FIN друг другу через приложение, но в случае полузакрытого TCP приложение укажет, чтособственные мысли: «Я завершил отправку данных и отправил сегмент FIN другой стороне, но я все еще хочу получать данные от другой стороны, пока она не отправит мне сегмент FIN». Ниже приведена схема полузакрытия TCP.

Объясните процесс:

Во-первых, хост-клиент и хост-сервер передают данные. Через некоторое время клиент отправляет сообщение FIN с запросом на активное отключение соединения. После получения FIN сервер отвечает ACK, потому что сторона который инициировал полузакрытие в это время, является Клиент все еще хочет, чтобы сервер отправлял данные, поэтому сервер будет продолжать отправлять данные. Через некоторое время сервер отправляет еще одно сообщение FIN. После того, как клиент получает сообщение FIN и отправляет ACK на сервер, соединение разрывается.

В режиме полузакрытия TCP одно направление соединения закрывается, в то время как другое направление все еще передает данные, пока не будет закрыто. Просто немногие приложения используют эту функцию.

Включение и выключение одновременно

Есть и более нестандартная операция, то есть два приложения одновременно активно открывают соединение. Хотя это может показаться маловероятным, это возможно при определенных условиях. В основном мы описываем этот процесс.

Две взаимодействующие стороны сначала отправят SYN перед получением SYN от другой стороны.Этот сценарий также требует, чтобы обе стороны знали SYN другой стороны.IP-адрес + номер порта.

Ниже приведен пример одновременного открытия

Как показано на рисунке выше, обе взаимодействующие стороны активно отправляли сообщение SYN перед получением сообщения друг друга, и обе отвечали сообщением ACK после получения сообщения друг друга.

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

Как и одновременное открытие, одновременное закрытие означает, что обе стороны связи делают активный запрос на закрытие в одно и то же время и отправляют сообщение FIN.На следующем рисунке показан процесс закрытия в одно и то же время.

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

Поговорим о начальном серийном номере

Возможно это непрофессиональная иллюстрация или текстовое описание выше.Первоначальный серийный номер представлен профессиональными терминами.Английское название исходного серийного номераInitial sequence numbers (ISN), поэтому выражение seq = v, которое мы выразили выше, на самом деле является ISN.

Перед отправкой SYN обе стороны выбирают начальный порядковый номер. Начальный порядковый номер генерируется случайным образом, и каждое TCP-соединение будет иметь другой начальный порядковый номер. В документации RFC указано, что начальный порядковый номер представляет собой 32-битный счетчик, который увеличивается каждые 4 мкс (микросекунды) + 1. Поскольку каждое TCP-соединение является отдельным экземпляром, цель такой схемы — предотвратить перекрытие порядковых номеров.

Когда соединение TCP установлено, другой стороне будет получен только правильный четырехугольник TCP и правильный порядковый номер. Это также свидетельствует о том, что TCP-сегмент легко взломать.伪造уязвимость, потому что, пока я подделываю один и тот же четверной и начальный порядковый номер, я могу подделать TCP-соединение, тем самым прервав нормальное соединение TCP, поэтому один из способов защиты от этой атаки — использовать начальный порядковый номер, другой — один из способов заключается в шифровании серийного номера.

Переходы состояния TCP

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

Первый шаг заключается в том, что в начале и сервер, и клиент находятся в состоянии ЗАКРЫТО, в это время необходимо судить, открыто ли оно открыто или пассивно, если активно открыто, клиент отправляет сообщение на сервер.SYNсообщение, клиент находится вSYN-SENDСтатус, SYN-SEND означает ожидание соответствующего запроса на подключение после отправки запроса на подключение, сервер будет находиться в пассивном открытом состоянииLISTENСтатус, используемый для мониторинга SYN-пакетов. Если клиент вызывает метод закрытия или не работает в течение определенного периода времени, он вернется в состояние ЗАКРЫТО.Схема перехода этого шага выглядит следующим образом.

Вот вопрос, почему клиент в состоянии LISTEN все равно отправляет SYN в состояние SYN_SENT?

Чжиху видел ответ Че Сяопана. Такая ситуация может возникнуть в FTP. LISTEN -> SYN_SENT, потому что это соединение может быть запущено приложением на стороне сервера, отправляющим данные клиенту, а клиент пассивно принимает соединение. , после того, как соединение установлено, начните передачу файлов. Другими словами, сервер в состоянии LISTEN также может отправить сообщение SYN, но это случается очень редко.

Сервер в состоянии SYN_SEND получает SYN и отправляет SYN и ACK вSYN_RCVDаналогично, клиент в состоянии LISTEN также получит SYN и отправит SYN и ACK для перехода в состояние SYN_RCVD. Если клиент в состоянии SYN_RCVD получаетRSTизменится на СЛУШАТЬ состояние.

Эти две картинки лучше смотрятся вместе.

Здесь нам нужно объяснить, что такое RST

Здесь возникает ситуация, когда хост получает сегмент TCP, а его IP и номера портов не совпадают. Предположим, клиентский хост отправляет запрос, а серверный хост обнаруживает, что он не для этого сервера, судя по IP и номеру порта, тогда сервер отправит запрос.RSTСпециальный сегмент для клиента.

Поэтому, когда сервер отправляет клиенту специальный сегмент RST, он сообщает клиентуНет подходящих сокетов, пожалуйста, не продолжайте отправку.

RST: (сбросить соединение)Используется для сброса ошибочного соединения по какой-либо причине, а также для отклонения незаконных данных и запросов.. Если получен бит RST, обычно возникает какая-то ошибка.

Неправильный указанный выше IP-порт является причиной возникновения RST.Кроме того, RST также может возникать из-за тайм-аута запроса, отмены существующего соединения и т. д.

Сервер на SYN_RCVD получит сообщение ACK, а клиент на SYN_SEND получит сообщения SYN и ACK и отправит сообщение ACK, таким образом, соединение между клиентом и сервером будет установлено.

Здесь следует отметить, что выше я не описывал состояние одновременного открытия, на самом деле в случае одновременного открытия изменение его состояния происходит так.

Почему это так? Потому что вы думаете, что в случае одновременного открытия оба хоста посылают SYN-сообщения, а хост, который активно инициирует SYN, будет находиться в состоянии SYN-SEND.После завершения передачи он будет ждать получения SYN и ACK, и оба хосты отправили его.После SYN+ACK обе стороны находятся в состоянии SYN-RECEIVED (SYN-RCVD), а после ожидания прихода сообщения SYN+ACK обе стороны будут в состоянии ESTABLISHED и начнут передавать данные .

Хорошо, пока я описал вам переходы состояний при установлении TCP-соединения, теперь можно заваривать чай, пить воду и ждать передачи данных.

Что ж, теперь, когда воды достаточно, передача данных также завершена.После завершения передачи данных TCP-соединение можно разорвать.

Теперь переводим часы вперед и подстраиваемся под момент, когда сервер находится в состоянии SYN_RCVD, т.к. только что получен пакет SYN и отправлен пакет SYN+ACK, сервер в это время очень доволен, но в этот время процесс серверного приложения закрывается. , а затем процесс приложения отправляетFINpackage, он позволит серверу из SYN_RCVD ->FIN_WAIT_1условие.

Затем настройте часы на настоящее время, клиент и сервер завершили передачу данных. В это время клиент отправляет сообщение FIN, чтобы отключить соединение. В это время клиент также станетFIN_WAIT_1Статус сервера, который получает сегмент FIN и отвечает сообщением ACK, изменится с ESTABLISHED ->CLOSE_WAITусловие.

Сервер в состоянии CLOSE_WAIT отправит сообщение FIN, а затем перейдет в состояние LAST_ACK. Когда клиент в состоянии FIN_WAIT_1 получает сообщение ACK, он переходит в состояние FIN_WAIT_2.

Здесь нам нужно сначала объяснить состояние ЗАКРЫТИЯ Преобразование FIN_WAIT_1 -> ЗАКРЫТИЕ является особенным.

ЗАКРЫТИЕ Это совершенно особое состояние, оно должно быть редким в реальных ситуациях и относится к относительно редкому состоянию исключения. В обычных обстоятельствах, когда вы отправляете сообщение FIN, само собой разумеется, что вы должны сначала получить (или одновременно получить) сообщение ACK другой стороны, а затем получить сообщение FIN другой стороны. Однако состояние CLOSING означает, что после отправки сообщения FIN вы не получили сообщение ACK другой стороны, а вместо этого получили сообщение FIN другой стороны.

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

Клиент в состоянии FIN_WAIT_2 получает сообщение FIN+ACK, отправленное хостом сервера, и после отправки ответа ACK становитсяTIME_WAITусловие. Клиент в состоянии CLOSE_WAIT отправляет FIN и находится в состоянии LAST_ACK.

Хотя на картинке много картинок и блогов, сообщение FIN+ACK будет в состоянии LAST_ACK, но при описании обычно описывается только FIN. Другими словами, CLOSE_WAIT будет находиться в состоянии LAST_ACK только при отправке FIN.

Таким образом, состояние FIN_WAIT_1 -> TIME_WAIT здесь — это состояние, в котором находится клиент после получения FIN и ACK и отправки ACK.

Затем, если клиент в состоянии CLOSINIG все еще получает ACK в это время, он будет продолжать находиться в состоянии TIME_WAIT.Видно, что состояние TIME_WAIT эквивалентно последнему состоянию клиента перед закрытием, которое является активным состояние закрытия и LAST_ACK Это последнее состояние сервера перед его закрытием, и это пассивное открытое состояние.

Существует несколько особого статуса выше, здесь мы объясним запад.

Статус TIME_WAIT

После того, как две взаимодействующие стороны установят TCP-соединение, сторона, которая активно закрывает соединение, войдет в состояние TIME_WAIT. Состояние TIME_WAIT также известно как2MSLсостояние ожидания. В этом состоянии TCP будет ждатьМаксимальное время жизни сегмента (MSL)вдвое больше времени.

MSL нужно объяснить здесь

MSL — это максимальное ожидаемое время жизни TCP-сегмента, то есть максимальное время его существования в сети. Это время ограничено, потому что мы знаем, что TCP полагается на сегменты IP-данных для передачи.В IP-датаграммах есть поля TTL и счетчика переходов.Эти два поля определяют время жизни IP.Максимальное время выживания составляет 2 минуты, но это значение может быть изменено, и это значение может быть изменено в соответствии с различными операционными системами.

Исходя из этого, давайте обсудим состояние TIME_WAIT.

Когда TCP выполняет активное закрытие и отправляет окончательный ACK, TIME_WAIT должен существовать в течение 2 * максимальное время жизни, что позволяет TCP повторно отправить окончательный ACK, чтобы избежать потери. Повторная передача окончательного ACK происходит не потому, что TCP повторно передал ACK, а потому, что другая сторона связи повторно передала FIN.Клиент часто отправляет FIN обратно, потому что ему нужен ответ ACK для закрытия соединения, если время выживания превышает 2MSL., клиент отправит RST, чтобы сделать сервер ошибкой.

Тайм-ауты TCP и повторные передачи

Нет связи, которая никогда не подводит, это предложение показывает, что какими бы совершенными ни были внешние условия, всегда будет возможность ошибки. Таким образом, в нормальном коммуникационном процессе TCP также будут возникать ошибки, которые могут быть вызваны потерей пакетов, дублированием пакетов или даже потерей пакетов.失序вызванный.

Во время процесса связи TCP принимающая сторона TCP вернет серию подтверждающей информации, чтобы определить, есть ли ошибка.Как только произойдет потеря пакета, TCP запустится.重传Операция по повторной передаче данных, которые еще не были подтверждены.

Существует два способа повторной передачи TCP, один из которых основан на时间, один основан на确认信息, как правило, передача подтверждающей информации более эффективна, чем передача времени.

Таким образом, с этого момента видно, что подтверждение и повторная передача TCP основаны на предпосылке того, подтвержден ли пакет данных.

TCP установиттаймер, если подтверждение не получено в течение времени, заданного таймером, будет инициирован соответствующий тайм-аут или операция повторной передачи на основе таймера.Время ожидания повторной передачи (RTO).

Но есть и другой способ, не вызывающий задержек, а именнобыстрая ретрансляция.

После того, как TCP будет каждый раз повторно передавать пакет, время его повторной передачи будет равно加倍, это "удвоение интервала" называетсядвоичная экспоненциальная отсрочка. После того, как интервал удвоится до 15,5 минут, клиент отобразит

Connection closed by foreign host.

TCP имеет два пороговых значения для принятия решения о повторной передаче сегмента, эти два пороговых значения определены в RFC[RCF1122], первое пороговое значениеR1, который указывает, сколько раз вы готовы попробовать повторную передачу, пороговое значениеR2Указывает, когда TCP должен разорвать соединение. R1 и R2 должны быть настроены как минимум на три повторные передачи и 100 секунд, чтобы разорвать соединение TCP.

Здесь следует отметить, что для сообщения об установлении соединения SYN его R2 должен быть установлен не менее 3 минут, но в разных системах значения R1 и R2 устанавливаются по-разному.

В системах Linux значения R1 и R2 могут быть установлены или изменены приложением.net.ipv4.tcp_retries1 и net.ipv4.tcp_retries2значение для установки. Значение переменной — количество повторных передач.

По умолчанию значение tcp_retries2 равно 15. Время ожидания для этого количества обогащений составляет около 13-30 минут.Это только приблизительное значение.Окончательное время ожидания также зависит от RTO, то есть времени ожидания повторной передачи. . Значение по умолчанию tcp_retries1 равно 3.

Для сегмента SYN два значения net.ipv4.tcp_syn_retries и net.ipv4.tcp_synack_retries ограничивают количество повторных передач SYN, по умолчанию 5, что составляет около 180 секунд.

В операционной системе Windows также есть переменные R1 и R2, и их значения определены в реестре ниже.

HKLM\System\CurrentControlSet\Services\Tcpip\Parameters
HKLM\System\CurrentControlSet\Services\Tcpip6\Parameters

Одной из очень важных переменных являетсяTcpMaxDataRetransmissions, этот TcpMaxDataRetransmissions соответствует переменной tcp_retries2 в Linux, значение по умолчанию равно 5. Это значение означает, сколько раз TCP не подтверждал сегмент в существующем соединении.

быстрая ретрансляция

Выше мы упомянули о быстрой повторной передаче.На самом деле, механизм быстрой повторной передачи запускается на основе информации обратной связи приемника, и на него не влияет таймер повторной передачи. Следовательно, по сравнению с повторной передачей по тайм-ауту, быстрая повторная передача может эффективно восстанавливать丢包условие. Когда пакеты с нарушением порядка (например, 2–4–3) поступают на принимающую сторону в процессе соединения TCP, протоколу TCP необходимо立刻Создайте подтверждающее сообщение, также известное какПовторить подтверждение.

Когда приходит пакет с нарушением последовательности, дубликат ACK должен быть возвращен немедленно, и никакая отложенная передача не допускается.Цель этого шага — сообщить отправителю, что определенный сегмент пакета поступил не по что отправитель может указать порядковый номер неупорядоченного сегмента пакета.

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

Как показано на рисунке выше, сегмент 1 успешно получен и подтвержден как ACK 2, а ожидаемый порядковый номер получателя равен 2. Когда сегмент 2 потерян, сегмент 3. Прибыл не по порядку, но не оправдал ожиданий получателя, поэтому получатель повторит избыточный ACK 2.

Таким образом, до истечения таймера повторной передачи тайм-аута, после получения трех последовательных идентичных ACK, отправитель знает, какой сегмент потерян, поэтому отправитель повторно передаст потерянный сегмент, так что нет необходимости ждать истечения таймера повторной передачи. значительно повышает эффективность.

SACK

В стандартном механизме подтверждения TCP, если отправитель отправляет данные с порядковыми номерами от 0 до 10000, а получатель получает только данные с номерами от 0 до 1000, 3000–10000, а данные с номерами от 1000 до 3000 не приходят на принимающую сторону, в это время отправитель будет повторно передавать данные между 1000 и 10000. На самом деле в этом нет необходимости, поскольку данные после 3000 были получены. Но отправитель не может воспринимать существование этой ситуации.

Как избежать или решить эту проблему?

Чтобы оптимизировать эту ситуацию, необходимо, чтобы клиент знал больше сообщений.В сегменте TCP существуетопция SACKполе, это поле представляет собой механизм **выборочного подтверждения**, этот механизм может сообщать TCP-клиенту, что объясняется в нашей общей поговорке: «Мне разрешено получать сегменты не более 1000, но я получил 3000-10000 сегментов, пожалуйста, дайте мне 1000-3000 сегментов".

Однако на то, включен ли этот механизм выборочного подтверждения, также влияет поле, котороеSACK разрешить параметрыполе, взаимодействующие стороны добавляют поле опции разрешения SACK в сегменте SYN или сегменте SYN + ACK, чтобы сообщить противоположному хосту, поддерживается ли SACK.Если обе стороны поддерживают его, опция SACK может быть использована в сегменте SYN позже.

Обратите внимание: поле опции SACK может отображаться только в сегменте SYN.

Псевдотайм-ауты и повторные передачи

В некоторых случаях повторные передачи пакетов могут происходить, даже если не происходит потери сегмента. Такое поведение при повторной передаче называетсяложная ретрансляция, эта повторная передача не требуется, факторы, вызывающие это, могут быть связаны сложный тайм-аут, Псевдо-тайм-аут означает, что происходит преждевременный тайм-аут оценки. Есть много факторов, которые вызывают ложные тайм-ауты, такие как неупорядоченное поступление сегментов, дублирование сегментов и потеря ACK.

Существует множество способов обнаружения и обработки ложных тайм-аутов, которые в совокупности называются检测алгоритм и响应алгоритм. Алгоритм обнаружения используется для определения того, имеет ли место феномен тайм-аута или феномен повторной передачи таймера. После тайм-аута или повторной передачи алгоритм ответа будет отменен или влияние тайм-аута будет смягчено. Ниже приведены несколько алгоритмов. В этой статье мы пока не будем вдаваться в подробности реализации.

  • Повторяющееся расширение SACK — DSACK
  • Алгоритм обнаружения Эйфеля
  • Прямое восстановление RTO — F-RTO
  • Алгоритм ответа Эйфеля

Неупорядоченность пакетов и дублирование пакетов

Выше мы обсудили, как TCP справляется с потерей пакетов, давайте обсудим проблему неупорядоченности и дублирования пакетов.

Пакет вне очереди

Прибытие пакетов данных не по порядку является чрезвычайно простой ситуацией в Интернете.Поскольку уровень IP не может гарантировать порядок пакетов данных, передача каждого пакета данных может выбрать канал с самой высокой скоростью передачи в текущей ситуации. Очень вероятно, что отправлены три пакета A -> B -> C, а порядок пакетов, прибывающих к получателю, следующий: C -> A -> B или B -> C -> A и так далее. Это феномен потери пакетов.

При передаче пакетов в основном используются два типа каналов: прямой канал (SYN) и обратный канал (ACK).

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

Если нарушение последовательности происходит на обратной линии связи, она перемещает окно TCP вперед, а затем получает повторные подтверждения ACK, которые следует отбросить, вызывая ненужные ошибки на стороне отправителя.всплеск трафика, что влияет на доступную пропускную способность сети.

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

Дублирование пакетов

Дублирование пакетов также является редким явлением в Интернете.Это относится к ситуации, когда пакеты могут передаваться несколько раз во время передачи по сети.При повторных передачах TCP может быть сбит с толку.

Дублирование пакетов может привести к тому, что получатель сгенерирует серию повторяющихся ACK, которые можно разрешить с помощью согласования SACK.

Потоковая передача TCP и управление окнами

мы в40 фотографий, которые помогут вам понять TCP и UDPВ этой статье известно, что скользящее окно может использоваться для достижения управления потоком, то есть клиент и сервер могут предоставлять друг другу обмен информацией о потоке данных.Соответствующая информация о потоке данных в основном включаетПорядковый номер сегмента, номер ACK и размер окна.

Две стрелки на рисунке представляют направление потока данных, которое также является направлением передачи TCP-сегмента. Как видите, каждый сегмент TCP включаетСерийный номер, ACK и информация об окне и, возможно, пользовательские данные. Размер окна в сегменте сообщения TCP указывает размер пространства кэша, способного получать приемный конец, в байтах. Этот размер окна - это динамический, поскольку будет приема и исчезновение сегмента сообщений и исчезновение, которое мы называем этой динамической регулировкой.滑动窗口, давайте внимательнее посмотрим на скользящее окно.

раздвижное окно

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

окно отправителя

Изображение ниже является примером окна отправителя.

На этом рисунке есть четыре концепции, связанные со скользящими окнами:

  • Сегменты, которые были отправлены и подтверждены: после отправки получателю получатель отвечает ACK, чтобы ответить на сегмент.Сегмент, отмеченный зеленым на рисунке, является сегментом, который был подтвержден получателем.
  • Сегменты, которые были отправлены, но еще не подтверждены: зеленая область на рисунке — это сегмент, который был подтвержден получателем, а светло-голубая область относится к сегменту, который был отправлен, но еще не подтвержден получателем.
  • Сегменты, ожидающие отправки: темно-синяя область на рисунке — это сегмент, ожидающий отправки, который является частью структуры окна отправки, то есть структура окна отправки фактически состоит из отправленного неподтвержденного + ожидающего отправки сообщения. сегменты .
  • Сегменты, которые могут быть отправлены только при скольжении окна: если сегменты из набора [4,9] на рисунке отправлены, все скользящее окно сдвинется вправо, а оранжевая область на рисунке может быть отправлена ​​только при окно перемещается в правый сегмент.

Скользящее окно также ограничено, и эта границаLeft edgeа такжеRight edge, Левый край — это левый край окна, Правый край — это правый край окна.

Когда левый край перемещается вправо, а правый край остается прежним, окно может бытьcloseНеполноценный. Это происходит по мере того, как отправленные данные постепенно подтверждаются, в результате чего окно становится меньше.

Когда правый край переместится вправо, окно будет вopenОткрытое состояние, чтобы разрешить отправку большего количества данных. Это состояние возникает, когда процесс-получатель считывает данные буфера, в результате чего буфер получает больше данных.

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

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

Каждый сегмент TCP содержитНомер ACK и информация об объявлении окна, поэтому всякий раз, когда получен ответ, получатель TCP настраивает структуру окна в соответствии с этими двумя параметрами.

Левый край скользящего окна TCP никогда не может двигаться влево, потому что отправленный и подтвержденный сегмент никогда не может быть отменен, точно так же, как в этом мире нет лекарства от сожалений. Этот край управляется номером ACK, отправленным другим сегментом. Окно вызывается, когда метка ACK перемещает окно вправо, но размер окна не изменяется.проведите вперед.

Если количество ACK увеличивается, но объявление окна становится меньше по мере поступления других ACK, левый край будет близок к правому краю. Когда левый край и правый край совпадают, отправитель больше не будет передавать данные, эта ситуация называется零窗口. В этот момент отправитель TCP инициирует窗口探测, дождитесь подходящего времени для отправки данных.

окно приемника

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

Подобно окну отправителя, структура окна получателя также поддерживает левый край и правый край. Сегменты, расположенные слева от левого края, называются принятыми и подтвержденными сегментами, а сегменты, расположенные справа от правого края, называются неприемлемыми сегментами.

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

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

Выше мы упоминали, что окно имеет левый край = правый край, который называется нулевым окном.Давайте подробно изучим нулевое окно.

нулевое окно

TCP реализует управление потоком через рекламную информацию окна получателя. Окно объявления сообщает TCP, сколько данных может получить получатель. Когда окно получателя становится равным 0, это может эффективно предотвратить отправку отправителем данных. Когда приемник восстанавливает доступное пространство, он передает窗口更新Сообщите себе, что вы можете получать данные. Обновления окна, как правило, представляют собой чистые ACK, то есть без каких-либо данных. Однако чистый ACK не может гарантировать, что он дойдет до отправителя, поэтому необходимы соответствующие меры для борьбы с такого рода потерей пакетов.

Если чистый ACK будет потерян, обе стороны связи будут в состоянии ожидания.Как может получатель, который хочет разорвать отправитель, позволить мне отправить данные! Принимающая сторона задается вопросом, почему отправитель до сих пор не отправляет данные! Чтобы предотвратить это, отправитель используетнепрерывный таймерПериодически опрашивайте приемник, чтобы увидеть, увеличилось ли его окно. Непрерывный таймер срабатывает窗口探测, заставляя получателя вернуть ACK с обновленным окном.

Оконные зонды содержат один байт данных, используя подход TCP с повторной передачей с потерями. Когда таймер сохраняемости TCP истекает, запускается отправка оконного зонда. Возможность получения байта данных получателем также зависит от размера его буфера.

контроль перегрузки

Благодаря оконному управлению TCP два хоста в компьютерной сети больше не отправляются в виде одного сегмента данных, а могут непрерывно отправлять большое количество пакетов данных. Однако большое количество пакетов также связано с другими проблемами, такими как загрузка сети, перегрузка сети и т. д. Чтобы предотвратить такие проблемы, TCP использует拥塞控制Механизм управления перегрузкой ограничивает передачу данных отправителя в случае перегрузки сети.

Существует два основных метода контроля перегрузки

  • 端到端的拥塞控制: поскольку сетевой уровень не обеспечивает явную поддержку управления перегрузкой на транспортном уровне. Таким образом, даже если в сети есть перегрузка, конечные системы должны делать выводы из наблюдений за поведением сети.TCP использует сквозное управление перегрузкой. Уровень IP не предоставляет конечным системам информацию о перегрузке сети. Так как же TCP определяет перегрузку сети?Если время ожидания или три раза, чтобы подтвердить, что он считается избыточным сетевым заложением, TCP уменьшит размер окна, либо увеличивает задержку отключения круглая, чтобы избежать.
  • 网络辅助的拥塞控制: при управлении перегрузкой с помощью сети маршрутизатор предоставляет отправителю обратную связь о состоянии перегрузки в сети. Эта информация обратной связи представляет собой бит информации, указывающий на перегрузку канала.

На следующем рисунке показаны эти два метода управления перегрузкой.

图片

Контроль перегрузки TCP

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

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

Но есть три проблемы с этим подходом

  1. Как отправитель TCP ограничивает скорость, с которой он может отправлять сегменты другим соединениям?
  2. Как отправитель TCP воспринимает перегрузку сети?
  3. Когда отправитель обнаруживает сквозную перегрузку, какой алгоритм он использует для изменения скорости отправки?

Сначала обсудим первый вопрос,Как отправитель TCP ограничивает скорость, с которой он может отправлять сегменты другим соединениям??

Мы знаем, что TCP состоит из буферов приема, буферов отправки и变量(LastByteRead, rwnd,等)сочинение. Механизм управления перегрузкой TCP отправителя отслеживает переменную, а именно拥塞窗口(congestion window)переменная, окно перегрузки выражается какcwnd, который ограничивает объем данных, которые TCP может отправить в сеть до получения ACK. а также接收窗口(rwnd)это объем данных, используемый, чтобы сообщить приемнику, что он может принять.

Как правило, количество неподтвержденных данных отправителем не должно превышать минимальное значение cwnd и rwnd, которое

LastByteSent - LastByteAcked <= min(cwnd,rwnd)

Поскольку время прохождения каждого пакета туда и обратно равно RTT, мы предполагаем, что у получателя достаточно места в буфере для приема данных, нам не нужно учитывать rwnd, просто сосредоточьтесь на cwnd, тогда скорость отправки отправителя примерно равнаcwnd/RTT 字节/秒. Таким образом, настраивая cwnd, отправитель может настроить скорость, с которой он отправляет данные в соединение.

Как отправитель TCP воспринимает перегрузку сети??

Это, как мы обсуждали выше, воспринимается TCP на основе тайм-аута или 3 избыточных ACK.

Когда отправитель обнаруживает сквозную перегрузку, какой алгоритм он использует для изменения скорости отправки? ?

Эта проблема более сложная, и позвольте мне объяснить, что в целом TCP будет следовать следующим руководящим принципам.

  • Если при отправке сегмент теряется, это означает, что сеть перегружена, и скорость TCP-отправителя необходимо соответствующим образом снизить.
  • Сегмент подтверждения указывает, что отправитель доставляет сегмент получателю, тем самым увеличивая скорость отправителя, когда приходит подтверждение для ранее неподтвержденного сегмента. Зачем? Поскольку неподтвержденный сегмент поступает к получателю, это означает, что сеть не перегружена и может доставляться гладко, поэтому длина окна перегрузки отправителя станет больше, поэтому скорость отправки увеличится.
  • 带宽探测, датчик полосы пропускания сообщает, что TCP может увеличивать/уменьшать количество ACK, регулируя скорость передачи, и в случае потери пакетов скорость передачи будет снижена. Следовательно, чтобы определить, как часто возникает перегрузка, отправитель TCP должен увеличить скорость передачи. Затем медленно уменьшите скорость передачи и снова начните исследование, чтобы увидеть, изменилась ли скорость возникновения перегрузки.

Разобравшись с управлением перегрузкой TCP, давайте поговорим о TCP.拥塞控制算法(TCP congestion control algorithm). Алгоритм управления перегрузкой TCP в основном состоит из трех частей: медленный старт, предотвращение перегрузки и быстрое восстановление Давайте рассмотрим его по очереди.

медленный старт

Когда TCP начинает устанавливать соединение, значение cwnd инициализируется меньшим значением MSS. Это делает начальную скорость отправки примерноMSS/RTT 字节/秒, например, для передачи 1000 байт данных и RTT 200 мс результирующая начальная скорость передачи составляет около 40 кбит/с. На практике доступная пропускная способность намного больше, чем этот MSS/RTT, поэтому, если TCP хочет найти наилучшую скорость отправки, он может пройти慢启动(slow-start)В режиме медленного пуска значение cwnd будет инициализировано до 1 MSS, и MSS будет добавляться после подтверждения каждого сообщения о передаче, а значение cwnd станет равным 2 MSS, эти два сегмента сообщения после успешной передачи каждый сегмент + 1 станет 4 MSS, и так далее, значение cwnd будет удваиваться при каждом успешном выполнении. Как показано ниже

图片

Скорость отправки не может постоянно увеличиваться, и увеличение всегда заканчивается, так когда же оно закончится? Медленный старт обычно заканчивается увеличением скорости отправки следующими способами.

  • Если потеря пакетов происходит во время процесса медленного запуска, TCP установит cwnd отправителя в 1 и перезапустит процесс медленного запуска, что приведет кssthresh(慢启动阈值)Его начальным значением является значение cwnd, которое выдает потерю пакетов/2, то есть при обнаружении перегрузки значение ssthresh составляет половину значения окна.
  • Второй способ напрямую связан со значением ssthresh, так как при обнаружении перегрузки значение ssthresh равно половине значения окна, тогда при cwnd > ssthresh возможна потеря пакетов каждый раз, когда оно удваивается, поэтому лучший способ что значение cwnd = ssthresh, так что TCP переключится в режим управления перегрузкой и завершит медленный старт.
  • Последний способ завершения медленного старта заключается в том, что при обнаружении 3 избыточных ACK TCP выполняет быструю повторную передачу и переходит в состояние восстановления.

предотвращение перегрузки

Когда TCP входит в состояние управления перегрузкой, значение cwnd равно половине значения во время перегрузки, т. е. значения ssthresh. Поэтому невозможно удваивать значение cwnd каждый раз, когда приходит сегмент. Вместо этого родственник保守метод, увеличивайте значение cwnd только после завершения каждой передачи一个 MSS, например, получены 10 подтверждений сегмента, но значение cwnd увеличивается только на один MSS. Это режим линейного роста, и у него тоже будет порог роста.Порог его роста такой же, как и у медленного старта.При потере пакетов значение cwnd равно MSS, а значение ssthresh равно половине cwnd; или Получение 3 избыточных ответов ACK также останавливает рост MSS. Если TCP по-прежнему получает 3 избыточных ACK после уменьшения вдвое значения cwnd, он запишет значение ssthresh как половину значения cwnd и введет快速恢复условие.

быстрое восстановление

При быстром восстановлении значение cwnd увеличивается на один MSS для каждого избыточного ACK, полученного для отсутствующих сегментов, чтобы перевести TCP в состояние быстрого восстановления. Когда приходит ACK для отсутствующего сегмента, TCP переходит в состояние предотвращения перегрузки после снижения cwnd. Если тайм-аут происходит после состояния управления перегрузкой, происходит переход в состояние медленного запуска, когда для параметра cwnd установлено значение 1 MSS, а для параметра ssthresh установлено значение половины значения cwnd.

У меня было шесть PDF-файлов, и вся сеть распространилась более чем на 10w+. После поиска «Programmer cxuan» в WeChat и подписки на официальный аккаунт я ответил cxuan в фоновом режиме и получил все PDF-файлы. следует

Шесть ссылок в формате PDF