Серия интервью по Java (1) --- Точный анализ протокола TCP

TCP/IP

0. Часто задаваемые вопросы

  • Вопросы интервью SF Express: Объясните процесс трехстороннего рукопожатия Tcp и четырехсторонней волны?
  • Вопросы интервью SF Express: уровни osi, уровни tcp/ip и роль каждого уровня?
  • Али вопросы интервью: В процессе установления и разрыва соединения TCP, как гарантировать, что информация, отправленная TCP, верна, и что ее последовательность не подделана?
  • Али вопросы интервью: три рукопожатия и четыре волны в TCP-соединении, какова функция последнего акка из четырех волн, зачем нужно время ожидания и зачем 2msl?
  • Главный вопрос сегодняшнего интервью: объясните управление перегрузкой TCP и управление потоком?

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

1.TCP/IP

1.1 Введение

Протокол TCP/IP (Протокол управления передачей/Интернет-протокол) — это не простой протокол, аспециальный набор протоколов, в том числе: TCP, IP, UDP, ARP и т. д. Они называются подпротоколами.

1.2 Слои

Оси семислойная модель

Эта фотография взята из: @ Zhihu Qiu Nuoyi

четырехуровневая модель TCP/IP

слой сетевого интерфейса:

Отвечает за мониторинг обмена данными между хостом и сетью; соответствует физическому уровню и уровню канала передачи данных в эталонной модели OSI. Фактически сам TCP/IP не определяет протокол этого уровня, и каждая сеть, участвующая во взаимосвязи, использует свои собственные протоколы физического уровня и канального уровня, а затем соединяется с уровнем доступа к сети TCP/IP.

межсетевой уровень:

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

транспортный уровень:

Включает диалоги между одноранговыми объектами на исходном и целевом компьютерах. На этом уровне определены два сквозных протокола: протокол управления передачей (TCP, протокол управления передачей) и протокол пользовательских дейтаграмм (UDP, протокол пользовательских дейтаграмм). TCP — это протокол, ориентированный на соединение, который обеспечивает надежную передачу пакетов и услуги соединения для приложений верхнего уровня. С этой целью, в дополнение к базовой передаче данных, он имеет такие функции, как обеспечение надежности, управление потоком, мультиплексирование, управление приоритетами и безопасностью. UDP — это ненадежный транспортно-ориентированный протокол без установления соединения, который в основном используется для приложений, не требующих функций упорядочивания и управления потоком TCP.

прикладной уровень:

Содержит все протоколы высокого уровня, в том числе: протокол виртуального терминала (TELNET, TELecommunication NETwork), протокол передачи файлов (FTP, протокол передачи файлов), протокол передачи электронной почты (SMTP, простой протокол передачи почты), службу доменных имен (DNS, доменное имя). Service) ), протокол передачи сетевых новостей (NNTP, протокол передачи сетевых новостей) и протокол передачи гипертекста (HTTP, протокол передачи гипертекста). TELNET позволяет пользователям на одном компьютере входить в систему и выполнять работу на удаленных компьютерах; FTP предоставляет средства для эффективного перемещения файлов с одного компьютера на другой; SMTP используется для отправки и получения электронной почты; DNS используется для сопоставления имен хостов с сетевыми адресами; NNTP для публикации, поиска и получения новостей; HTTP для получения домашних страниц в Интернете.

1.3 TCP

1.3.1 Введение

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

1.3.2 Подключение

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

1.3.2.1 Трехстороннее рукопожатие

Давайте сначала посмотрим на структуру пакета данных tcp:

Необходимо выделить несколько заштрихованных полей:

  1. Порядковый номер: Seq (Порядковый номер) Порядковый номер занимает 32 бита и используется для идентификации порядкового номера пакета данных, отправляемого с компьютера А на компьютер Б, который отмечается, когда компьютер отправляет данные.

  2. Номер подтверждения: Ack (Acknowledge Number) номер подтверждения занимает 32 бита, который может быть отправлен как клиентом, так и сервером, Ack = Seq + 1.

  3. Бит флага: каждый бит флага занимает 1 бит, всего их 6, это URG, ACK, PSH, RST, SYN, FIN, конкретные значения следующие:

  • SYN (синхронное установление соединения)
  • ACK (подтверждение подтверждения)
  • ПШ (нажимная передача)
  • FIN (конец конца)
  • RST (сброс)
  • УРГ (неотложная помощь)

Как установить соединение?

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

В программировании сокетов, когда клиент выполняет функцию connect(), он инициирует трехэтапное рукопожатие.

1) Хост A отправляет флаг syn=1 и случайным образом генерирует на сервер пакет данных seq=x. Хост B известен как syn=1, и A запрашивает установление соединения, в это время состояние A равно SYN_SENT, а B — LISTEN.

2) После получения запроса хост B должен подтвердить информацию о соединении и отправляет ack=(seq+1 хоста A) на A, флаги syn=1, ack=1, и пакет seq=y передается случайным образом. В это время состояние A — ESTABLISHED, B — SYN_RCVD.

3) После того, как хост А получит его, проверьте правильность акка, то есть, отправлен ли seqnumber+1 в первый раз, и битовый код акка равен 1, если он правильный, хост А снова отправит акк = (seq+1 хоста B), флаг ack=1, хост B подтверждает значение seq и ack=1 после его получения, соединение установлено успешно. В это время оба состояния А и В становятся УСТАНОВЛЕННЫМИ.

Почему TCP не подключается дважды? Но трехстороннее рукопожатие?

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

1.3.2.2 SYN-атака

Что такое SYN-флуд?

В процессе трехстороннего рукопожатия после того, как сервер отправляет SYN-ACK, TCP-соединение до получения ACK от клиента называется полуоткрытым соединением. Теперь сервер находится в состоянии SYN_RCVD. При получении ACK сервер может перейти в состояние ESTABLISHED.

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

SYN-атака — типичная DoS/DDoS-атака.

Как обнаружить SYN-атаки?

Очень удобно обнаруживать SYN-атаки, когда вы видите большое количество полусоединенных состояний на сервере, особенно IP-адрес источника является случайным, вы можете в принципе сделать вывод, что это SYN-атака. В Linux/Unix вы можете использовать встроенную команду netstats для обнаружения SYN-атак.

Как защититься от SYN-атак?

Атаки SYN нельзя полностью предотвратить, если протокол TCP не будет переработан. Что мы делаем, так это максимально снижаем вред от SYN-атак.Общими методами защиты от SYN-атак являются следующие:

  • Сократите время ожидания SYN
  • Увеличьте максимальное количество полусоединений
  • Фильтр защиты шлюза
  • Технология файлов cookie SYN

1.3.3 Передача данных

Как только соединение установлено, два хоста могут передавать данные друг другу. Как показано ниже:

На приведенном выше рисунке показан процесс, когда узел A передает 200 байт на узел B за 2 раза (2 пакета).

  1. Во-первых, хост А отправляет 100 байт данных в 1 пакете, а для порядкового номера пакета установлено значение 1200.

  2. Чтобы подтвердить это, хост B отправляет пакет ACK на хост A с номером подтверждения, равным 1300.

Чтобы гарантировать, что данные поступают точно, целевая машина должна вернуть пакет ACK сразу после получения пакета данных (включая пакет SYN, пакет FIN, обычный пакет данных и т. д.), чтобы отправитель мог подтвердить успешную передачу данных. .

Номер подтверждения теперь равен 1300 вместо 1200, поскольку номер подтверждения увеличивается на количество переданных байтов данных.

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

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

Ниже приведен анализ потери пакетов во время передачи, как показано на следующем рисунке:

На приведенном выше рисунке показано, что 100 байт данных передаются хосту B через пакет Seq 1300, но в середине происходит ошибка, и хост B не получает их. Через некоторое время хост A не получил ACK для Seq 1300, поэтому он пытается повторно передать данные.

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

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

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

1.3.3.1 Процесс надежной передачи

Каким образом в описанном выше процессе передачи данных протокол tcp обеспечивает надежную передачу данных?

(1) Чтобы обеспечить надежную доставку пакетов данных, отправитель должен хранить отправленные пакеты данных в буфере;

(2) и запускать таймер тайм-аута для каждого отправленного пакета;

(3) Если ответная информация от другой стороны получена до истечения таймера, буфер, занятый пакетом данных, освобождается;

(4) В противном случае повторно передавать пакет данных до тех пор, пока не будет получен ответ или количество повторных передач не превысит указанное максимальное число.

(5) После того, как приемник получает пакет данных, он сначала выполняет проверку CRC (код проверки циклическим избыточным кодом для обеспечения правильности и целостности передачи данных), если он правильный, данные передаются протоколу верхнего уровня, и затем отправляется отправителю. Совокупный ответный пакет указывает на то, что данные были получены. Если получатель также имеет данные для отправки отправителю, ответный пакет также может быть включен в пакет данных.

1.3.3.2 Повторная передача по тайм-ауту и ​​быстрая повторная передача для надежной передачи  

  • Тайм-аут повторной передачи: когда тайм-аут истекает, отправитель повторно передает пакет данных до получения подтверждения ACK от однорангового узла.
  • Быстрая повторная передача: когда следующие порядковые номера приходят первыми, если получатель получает 1, 3 и 4, но 2 не получен, он немедленно трижды повторно передает запрос подтверждения ACK=2 отправителю. Если отправитель получает 3 последовательных ACK с одинаковым порядковым номером, он повторно передает пакет. вместо ожидания тайм-аута.

1.3.3.3 Управление потоком для надежной передачи

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

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

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

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

1.3.3.4 Контроль перегрузки для надежной передачи

Почему контроль перегрузки?

Чтобы ответить на этот вопрос, вы должны сначала узнать, когда происходит перегрузка TCP. Как сквозной протокол транспортного уровня, TCP не заботится о том, сколько маршрутизаторов и коммутаторов будут проходить две стороны по физическому каналу, а также о пути и следующем пути для передачи пакетов.Это то, что должен учитывать уровень IP. . Однако в реальных сетевых приложениях два конца TCP-соединения могут быть разделены тысячами миль, и пакеты должны пересылаться несколькими маршрутизаторами и коммутаторами. Производительность коммутационного устройства не безгранична!Когда пакеты от нескольких входящих интерфейсов пересылаются с одного и того же исходящего интерфейса,Если скорость пересылки исходящего интерфейса достигает предела, пакеты начинают накапливаться в буферной очереди входящего интерфейса коммутационного устройства. Однако длина очереди также ограничена: при заполнении очереди последующие входящие пакеты могут быть только отброшены.. Для отправителя TCP они видят, что пакет потерян, когда тайм-аут отправлен.

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

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

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

Разница между rwnd и cwnd
Понятия rwnd (окно получателя, окно получателя) и cwnd (окно перегрузки, окно перегрузки): rwnd: размер окна, используемый для управления потоком, то есть AdvertisedWindow в приведенном выше управлении потоком, который в основном зависит от скорости обработки получателя, и получатель информирует отправителя о необходимости пассивной настройки (подробную логику см. выше).
cwnd: размер окна для обработки перегрузки, зависящий от состояния сети, который активно настраивается отправителем для проверки сети.
При введении управления потоком мы не учитывали cwnd, а считали, что максимальное скользящее окно отправителя равно rwnd. На самом деле управление потоком и обработку перегрузки необходимо учитывать одновременно, чтобы размер окна отправителя не превышал min{rwnd, cwnd}. Следующие четыре алгоритма управления перегрузкой включают только регулировку cwnd.Как и при введении управления потоком, rwnd пока не рассматривается, и предполагается, что максимальное скользящее окно равно cwnd. rwnd, cwnd и размер окна отправителя.

Четыре алгоритма управления перегрузкой

С момента рождения TCP существовало множество алгоритмов управления перегрузкой, и до сих пор предлагались новые! где TCPTahoe(1988)и TCPReno(1990)первые два алгоритма. Хотя он выглядит очень старым,RenoАлгоритмы все еще широко используются сегодня.

Tahoe 提出了  1)慢启动,2)拥塞避免,3)快速重传
Reno 在Tahoe的基础上增加了 4)快速恢复

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

Алгоритм медленного запуска алгоритма управления перегрузкой

Алгоритм медленного старта (Slow Start) действует до возникновения перегрузки: для только что присоединившегося к сети соединения необходимо увеличивать скорость понемногу, а не пытаться добиться этого за один прием. следующим образом:

连接刚建好,初始化cwnd = 1(当然,通常不会初始化为1,太小),表明可以传一个MSS大小的数据。
每收到一个ACK,cwnd++,线性增长。
每经过一个RTT,cwnd = cwnd * 2,指数增长(主要增长来源)。
还有一个ssthresh(slow start threshold),当cwnd >= ssthresh时,就会进入拥塞避免算法(见后)。

Следовательно, если скорость сети высокая, Ack возвращается быстро, а RTT короткий, то этот медленный старт вовсе не медленный. Следующая диаграмма иллюстрирует этот процесс:

ПРИМЕЧАНИЕ 4RFC 2581 уже позволяетcwndНачальное значение максимума равно 2, что уже разрешено RFC 3390.cwndНачальное значение максимума равно 4, что уже разрешено RFC 6928.cwndНачальное значение максимума равно 10

Алгоритм предотвращения перегрузки алгоритма управления перегрузкой

Как упоминалось ранее, когда cwnd >= ssthresh (обычно ssthresh = 65535), он войдет в алгоритм предотвращения перегрузок (Congestion Avoidance): медленно расти и тщательно находить оптимальное значение. следующим образом:

每收到一个Ack,cwnd = cwnd + 1/cwnd,显然,cwnd > 1时无增长。
每经过一个RTT,cwnd++,线性增长(主要增长来源)。

Алгоритм медленного старта в основном растет экспоненциально, грубо и быстро («медленно» относится к одному шагу), в то время как алгоритм предотвращения перегрузки в основном растет линейно, точно и медленно, но легче избежать перегрузки. оптимальное значение cwnd для сетевой среды.

Быстрый алгоритм повторной передачи алгоритма управления перегрузкой

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

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

Алгоритм быстрого восстановления алгоритма управления перегрузкой

Если срабатывает быстрая ретрансляция, то есть отправитель получает один и тот же Ack минимум 3 раза, то TCP думает, что ситуация в сети не так уж и плоха, и волноваться по этому поводу не стоит, и может восстанавливаться адекватно и смело . Для этого разработан алгоритм быстрого восстановления (Fast Recovery), реализация которого в TCP Reno описана ниже.

Напомним, что cwnd и sshthresh были обновлены перед переходом в режим быстрого восстановления:

ssthresh = cwnd /2
cwnd = cwnd /2

Затем введите алгоритм быстрого восстановления:

cwnd = ssthresh + 3 * MSS (尝试一步到位)
重传重复Ack对应的Seq
如果再收到该重复Ack,则cwnd++,线性增长(缓慢调整)
如果收到了新Ack,则cwnd = ssthresh ,然后就进入了拥塞避免的算法了

1.3.4 Отключение

Протокол завершения соединения (четырехстороннее рукопожатие)

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

  • Процесс приложения A сначала отправляет сегмент освобождения соединения (FIN=1, порядковый номер seq=u) в свой TCP, снова прекращает отправку данных, активно закрывает TCP-соединение, переходит в состояние FIN-WAIT-1 (ожидание завершения 1) , и ждет подтверждения B.
  • После того, как B получает сегмент освобождения соединения, он отправляет сегмент подтверждения (ACK=1, номер подтверждения ack=u+1, порядковый номер seq=v), и B переходит в состояние CLOSE-WAIT (ожидание закрытия). , TCP В полузакрытом состоянии соединение от A к B освобождается.
  • Получив подтверждение от B, A переходит в состояние FIN-WAIT-2 (ожидание завершения 2) и ожидает сегмента освобождения соединения, отправленного B.
  • У B нет данных для отправки A, B отправляет сегмент освобождения соединения (FIN=1, ACK=1, порядковый номер seq=w, номер подтверждения ack=u+1), и B входит в LAST-ACK (последнее подтверждение) состояние, Дождитесь подтверждения от А.
  • После того, как A получает сегмент освобождения соединения от B, он отправляет сегмент подтверждения (ACK=1, seq=u+1, ack=w+1), и A переходит в состояние TIME-WAIT (время ожидания). В это время TCP не освобождается, и ему необходимо выждать время, установленное таймером 2MSL, прежде чем A перейдет в состояние CLOSED.

Почему установление протокола соединения представляет собой трехстороннее рукопожатие, а закрытие соединения — четырехстороннее рукопожатие?
Это связано с тем, что когда SOCKET в состоянии LISTEN сервера получает запрос на установление соединения сообщения SYN, он может отправить ACK и SYN (ACK действует как ответ, а SYN действует как синхронизация) в одном пакете для отправки. Но при закрытии соединения, при получении уведомления о сообщении FIN другой стороны, это означает только то, что у другой стороны нет данных для отправки вам; но не все ваши данные отправляются другой стороне, поэтому вы не можете сразу закрыть SOCKET, То есть вам также может потребоваться отправить некоторые данные другой стороне, а затем отправить другой стороне сообщение FIN, чтобы указать, что вы согласны с тем, что соединение теперь может быть закрыто, поэтому сообщение ACK и сообщение FIN здесь отправляются отдельно в большинстве случаев.

1.3.4.1 Статус FIN_WAIT_2

В состоянии FIN_WAIT_2 мы выдали FIN, и другая сторона также подтвердила это. если мы не Линия наполовину закрыта, иначе она будет ждать, пока прикладной уровень на другой стороне поймет, что он получил спецификацию конца файла, и отправит нам сообщение. FIN, чтобы закрыть соединение в другом направлении. Только когда процесс на другом конце завершит это отключение, наш конец Состояние FIN_WAIT_2 переходит в состояние TIME_WAIT. Это означает, что наш конец может остаться в этом состоянии навсегда. Другой конец также будет находиться в состоянии CLOSE_WAIT и всегда будет Сохраняйте это состояние до тех пор, пока прикладной уровень не решит завершить работу. Многие реализации Беркли предотвращают это бесконечное ожидание в состоянии FIN_WAIT_2 следующим образом. Если вы выполните Прикладной уровень, который активно закрыт, будет полностью закрыт, а не наполовину закрыт, чтобы указать, что он все еще хочет получать данные, поэтому установите таймер. Если соединение не используется в течение 10 минут и 75 секунд, TCP перейдет в состояние ЗАКРЫТО. В комментариях кода реализации подтвердите, что код реализации нарушает спецификацию протокола.

1.3.4.2 2MSL

Что такое 2МСЛ? MSL — это максимальное время жизни сегмента, т.Максимальное время жизни пакета, цитируя слова в «Подробном объяснении TCP/IP»: «Это(MSL) — это максимальное время в сети до того, как какой-либо сегмент будет отброшен., то 2MSL в два раза больше этого времени.Когда TCP-соединение завершит обмен четырьмя сегментами, сторона, которая активно закрывается, будет продолжать ждать в течение определенного периода времени (2-4 минуты), даже если приложения на обоих концах завершатся .

Почему состояние TIME_WAIT должно пройти 2MSL (максимальное время жизни сегмента), чтобы вернуться в состояние CLOSE?

Во-первых: убедитесь, что последнее сообщение ACK, отправленное клиентом, может достичь сервера, потому что это сообщение ACK может быть потеряно.С точки зрения сервера, я отправил сообщение FIN+ACK с запросом на отключение, а клиент по-прежнему не отвечает было дано мне, должно быть так, что отправленное мной сообщение об отключении запроса не было получено, поэтому сервер повторно отправит его, и клиент может получить повторно переданное сообщение в течение этого периода времени 2MSL, а затем дать ответное сообщение отправлено, и таймер 2MSL перезапускается.
Во-вторых: предотвратить появление «недопустимого сегмента запроса на соединение», упомянутого в «трехстороннем рукопожатии», в этом соединении, то есть после закрытия TCP-соединения немедленно восстановить тот же IP-адрес и TCP-соединение между портами, последнее соединение называется воплощением прежнего соединения, то такая ситуация возможна. После того, как клиент отправит последнее подтверждающее сообщение, в течение этого времени 2MSL все сегменты сообщений, сгенерированные во время этого соединения, могут быть удалены из сети. Таким образом, сообщение запроса старого соединения не появится в новом соединении.

Влияние на сервер?

Когда один конец соединения находится в состоянии TIME_WAIT, соединение больше нельзя использовать. На самом деле для нас более реалистично то, чтоЭтот порт больше не будет использоваться. Когда порт находится в состоянии TIME_WAIT (на самом деле это должно быть это соединение), это означает, что TCP-соединение не разорвано (полностью разъединено), тогда, если вы привяжете этот порт, произойдет сбой. Для сервера, если сервер внезапно выйдет из строя, он не сможет перезапуститься в течение 2MSL, поскольку привязка не будет выполнена. Один из способов решить эту проблему — установить сокетSO_REUSEADDRопции. Эта опция означает, что вы можете повторно использовать адрес.

1.3.4.3 Случаи и решения

1. Статья о самородкахnuggets.capable/post/684490…

2. Личный блог:Smurfs.GitHub.IO/2016/02/27/…

1.3.5 диаграмма замены состояния TCP

2 Резюме

Вышеупомянутая статья описывает процесс протокола tcp от установления до передачи данных и отключения. Статья является результатом сбора многих статей в Интернете, и мое понимание также ограничено.Если вы обнаружите какие-либо проблемы, пожалуйста, укажите вовремя.

Если у вас есть хорошие вопросы для интервью о tcp, пожалуйста, оставьте мне сообщение ниже! ! ! Спасибо! ! !