Зачем нужен ACK от инициатора в TCP-соединении?

Вопрос не является дубликатом эта ссылка . Поскольку это спрашивает, почему нам нужно трехстороннее дрожание рук, и я знаю, почему! мой вопрос заключается в том, почему пакет ACK не может быть адаптирован следующим протокольным пакетом (PSH ACK).

Я понимаю, почему существует необходимость в рукопожатии, но нужен ли нам ACK в конце от initater? Давайте возьмем пример HTTP-запроса, за которым последовало рукопожатие TCP.

CLIENT:23434 SN 0 -----> SERVER:80 -- SYN
CLIENT:23434 <----- SERVER:80 SN 0, AN 1 -- SYN ACK
CLIENT:23434 SN 1 AN 1 -----> SERVER:80 -- ACK
CLIENT:23434 SN 1 AN 1 -----> SERVER:80 -- PSH ACK(HTTP GET)

Теперь, если должен быть пакет протокола (данных), за которым следует ACK трехстороннего рукопожатия с тем же порядковым номером и номером подтверждения, почему пакет ACK почему бы не использовать пакет протокола только для синхронизации?

3 голоса | спросил Anirudh Malhotra 31 +03002016-10-31T21:22:25+03:00312016bEurope/MoscowMon, 31 Oct 2016 21:22:25 +0300 2016, 21:22:25

3 ответа


2

Похоже, вы спрашиваете, почему, если клиент сначала отправляет данные, клиент не может объединить голые рукопожатие с этими данными.

Но я думаю, что это возможно - это просто не так. API-интерфейсы операционной системы являются типичной причиной .. сокет обычно не принимает данные для записи () n, когда он не находится в установленном состоянии, и ядро, увидев syn /ack, не будет ждать, чтобы увидеть если пользовательское пространство отправляет некоторые данные перед отправкой ack. (поскольку ядро ​​не знает, какой конец этого биди-соединения будет писать первым, а другой конец не сможет записать, пока не получит завершенное рукопожатие).

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

ответил Patrick McManus 31 +03002016-10-31T23:55:03+03:00312016bEurope/MoscowMon, 31 Oct 2016 23:55:03 +0300 2016, 23:55:03
2

Отличный вопрос. Я согласен, что это не дубликат другого.

Цель трехстороннего рукопожатия - установить двунаправленный канал связи . Сообщение, которое происходит внутри , выходит за пределы области TCP.

Иногда для Клиента устанавливается соединение для отправки чего-либо на Сервер. В других случаях устанавливается соединение для того, чтобы Сервер отправил что-то Клиенту. TCP должен учитывать оба этих случая.

Повторное цитирование вашей иллюстрации связи для простоты и добавления номеров строк:

#1   SN 0 -----> SERVER:80 -- SYN
#2   <----- SERVER:80 SN 0, AN 1 -- SYN ACK
#3   SN 1 AN 1 -----> SERVER:80 -- ACK
#4   SN 1 AN 1 -----> SERVER:80 -- PSH ACK(HTTP GET)

Если протокол с использованием TCP ведет себя как HTTP, где первая передача данных после установления соединения - это Клиент, отправляющий данные на сервер , то вы правы, чтобы сказать, что одиночный ACK (строка № 3) кажется лишним. Прямой предел пакета (строка № 4) будет достаточным, чтобы сообщить Серверу, что Клиент получил их ISN (из строки # 2).

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

Это более редко встречается в Интернете, но оно существует. Оффлайн, я могу подумать о Passive FTP, где клиент инициирует соединение для передачи данных (он же отправляет исходный SYN), но цель подключения заключается в том, что сервер отправляет исходный пакет данных - который начинается, как только соединение с данными .

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

ответил Eddie 31 +03002016-10-31T23:21:56+03:00312016bEurope/MoscowMon, 31 Oct 2016 23:21:56 +0300 2016, 23:21:56
1

Да, есть необходимость в пустом значении для подтверждения отправки syn с другого конца

(closed) A <syn>----------> B (listen) 
(syn-sent) A <------------<syn><ack> B (listen) 
(established) A               B (syn-sent)

Как после этих шагов B ждет ACK от A для SYN, чтобы достичь установленного состояния соединения.

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

  (established) A <ack>-----------> B (syn-sent)
  (established) A [data>]<ack>-----------> B (established)

с

 (established) A [<data>]<ack>-----------> B (syn-sent)

Но, как кажется, B находится в неустановленном состоянии, он, кажется, не развлекает полезную нагрузку

  

В RFC 793 (раздел 3.4. Установление соединения)

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

, поэтому из rfc кажется

4 SN 1 AN 1 -----> SERVER:80 -- PSH ACK(HTTP GET)

будет буферизирован и будет доставлен в приложение только после того, как после него будет указан пустой знак

Ваше решение может работать для реализации под названием delayed ack

ответил 8zero2.ops 1 22016vEurope/Moscow11bEurope/MoscowTue, 01 Nov 2016 15:28:34 +0300 2016, 15:28:34

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132