Назад | Перейти на главную страницу

Почему TCP-сервер ожидает ACK, когда на стороне клиента доступно достаточное окно

Я наблюдаю приведенное ниже поведение в TCP-соединении между серверным приложением и клиентом, которые работают на двух разных машинах Red Hat.

Пример 1

  1. Клиент подтверждает все до сих пор (ACK с WND = 1424)
  2. Сервер отправляет 296 байтов на уровень TCP, и он отправляется клиенту (PUSH / ACK)
  3. Сервер отправляет 296 байтов на уровень TCP, и он отправляется клиенту (PUSH / ACK)
  4. Сервер отправляет 296 байтов на уровень TCP, и он отправляется клиенту (PUSH / ACK)
  5. Сервер отправляет / пытается отправить 239 байтов на уровень TCP, но: происходит одно из следующих двух
    1. ОС ожидает ~ 30 мсек, пока ACK от клиента не будет получен, прежде чем отправлять эти байты (эта отправка x байтов будет называться отложенным сообщением ниже)
    2. вызов tcp send возвращает EWOULDBLOUCK или EAGAIN (я думаю, что это невозможно, потому что 239 + 239 + 239 + 239 <1424. Пожалуйста, поправьте меня, если я ошибаюсь

Пример 2

  1. Клиент подтверждает все до сих пор (ACK с WND = 1424)
  2. Сервер отправляет 239 байтов на уровень TCP, и он отправляется клиенту.
  3. Сервер отправляет / пытается отправить 239 байтов на уровень TCP, и происходит одно из двух перечисленных выше событий.

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

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

  1. Серверное приложение не передает «отложенное сообщение» на уровень TCP, потому что системный вызов send вернул EWOULDBLOUCK или EAGAIN.
  2. Приложение передает сообщение на уровень TCP, но операционная система не отправляет его до тех пор, пока не будет получен ACK от клиента.

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

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

  1. Это какая-то настройка уровня ОС, которую я могу установить на стороне клиента или сервера
  2. Это как-то ошибка сервера приложений?
  3. Я ошибаюсь, предполагая, что ОС не возвращает EWOULDBLOCK, пока сообщения не заполнят окно

изменить: Причина дублирования: я не был уверен, в чем проблема; сеть / os. Я добавил дополнительные детали. Кроме того, мне нужен POV из TCP-реализации Linux, поэтому я думаю, что этот вопрос принадлежит к этому вопросу.

Это называется «отложенным ACK» и так работает протокол TCP. Видеть https://en.m.wikipedia.org/wiki/TCP_delayed_acknowledgment Больше подробностей. Вы можете отключить эту функцию, если она влияет на производительность ваших приложений. Скажем, iSCSI отключил отложенное подтверждение ACK по умолчанию.