подтверждение TCP не гарантирует, что данные были доставлены

11

В RFC 793 есть часть о подтверждении сегментов TCP:

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

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

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

Но теперь этот RFC заставил меня задуматься - что еще я должен проверить (без настройки Wireshark), если установлено соединение TCP, но у пользователей все еще возникают проблемы с подключением?

kamokoba
источник
5
Это предложение означает просто буквальное английское значение предложения: тот факт, что сетевой драйвер получил данные (и подтвердил получение), не гарантирует, что конечный пользователь получит данные. Например, на веб-сервере может быть ошибка. Что касается вашего заключительного вопроса: единственный способ выяснить, получил ли конечный пользователь данные, это позвонить им и спросить их.
Йорг Миттаг

Ответы:

24

Эта часть RFC касается передачи ответственности операционной системе или какому-либо следующему этапу процесса. Это в основном связано с разделением слоев.

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

Я всегда думал об этом так:

  • Может произойти сбой ОС между отправкой ACK и данными, достигающими клиентского процесса (здесь «клиент» означает клиент ОС, а не «сетевой клиент»)
  • Клиентский процесс может быть с ошибкой или сбоем, или просто намного медленнее, чем ожидалось, чтобы справиться с обработкой входящих данных, или даже прочитать его только при неочевидных обстоятельствах.
  • Если клиент отправляет данные вперед, возможно, в файл на диске, файл, возможно, еще не был записан или очищен
  • Если клиент отправляет данные по протоколу TCP, TCP удаленной стороны, возможно, не передал данные, не получил ACK, или удаленный процесс успешно использовал данные

Все, что он говорит, это то, что это подтверждение уровня 3 («Я слышу ваши байты»), а не подтверждение более высокого уровня . Рассмотрим, например, различие между TCP ACK, SMTP 250 OKпосле того, как почтовый шлюз следующего перехода принимает сообщение, сообщение о получении сообщения (например, согласно RFC 3798 ), пиксель отслеживания открытого сообщения, благодарственное письмо от PA, и ответ: «Да, я сделаю это».

Другим конкретным примером будет принтер:

  • Он должен получить данные заранее, прежде чем узнает, что в них содержится (это может быть файл Postscript, начинающийся с включенной библиотеки, превышающей окно передачи TCP)
  • Он может содержать запрос статуса («у вас есть бумага?», Который он, очевидно, может выполнить)
  • Он может содержать команду печати («пожалуйста, распечатайте это», что может привести к сбою в случае отсутствия бумаги)

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

Для диагностики я предлагаю искать ретрансляторы, а не конкретно ACK.

jonathanjo
источник
Еще один пункт: даже если клиентский процесс работает нормально, он может еще не прочитать данные.
Бармар
1
Клиентский процесс (если он чувствует себя ленивым или извращенным) может просто никогда не вызвать recv()сокет, и в этом случае полученные данные будут оставаться в буфере приема сокета TCP на неопределенный срок.
Джереми Фриснер
Спасибо обоим, обновил его, чтобы предложить клиентский процесс может быть медленным, глючным, переменчивым.
Джонатанджо
Вы не можете полагаться на ACK, чтобы гарантировать, что приложение обработало ваш ввод, вы должны реализовать прикладной уровень ACK или Check. Чтобы поместить это в другой контекст. Для промышленных сетей управления, использующих TSN с IP-стеком на стороне клиента, TCP ACK недостаточно для гарантии того, что переменные процесса были зафиксированы. То есть вы не можете полагаться на TCP ACK для перевода системы в безопасное или исправное состояние, вы должны получить подтверждение от службы прикладного уровня о том, что можно безопасно засунуть руку в машину.
авария
10

С точки зрения RFC, «конечный пользователь» - это приложение. Нет гарантии, что приложение получило данные, только то, что процесс TCP получил их.

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

Рон Транк
источник
0

Вы могли видеть это таким образом.

Вы - M.Smith, и вы хотите отправить письмо M.Toto (лица - это слой приложения).

Чтобы отправить письмо, отправляйтесь в местное почтовое отделение A, которое отправит письмо в местное почтовое отделение B M.Toto (почтовые отделения являются уровнем TCP).

Все может быть хорошо между вами, почтовое отделение A и почтовое отделение B - B отправят ACK на почтовое отделение A. Но ничто не гарантирует, что письмо прибудет в M.Toto. Что-нибудь могло случиться между почтовым отделением B и M.Toto.

Это в основном то, что говорит RFC.

тото
источник