Кто устанавливает размер окна TCP до 0, Indy или Windows?

У нас есть сервер приложений, который наблюдал отправку заголовков с размером окна TCP 0 в то время, когда сеть была перегружена (на сайте клиента).

Мы хотели бы знать, является ли Indy или нижележащий уровень Windows ответственным за уменьшение размера окна TCP от номинального 64K в соответствии с доступной пропускной способностью.
И мы сможем действовать, когда он станет 0 (ничего не отправляется, пользователи ждут => ничего хорошего).

Так что любая информация, ссылка, указатель на код Indy приветствуются...

Отказ от ответственности: я не специалист по сети. Пожалуйста, держите ответ понятным для среднего меня;-)
Примечание: это Indy9/D2007 на Windows Server 2003 SP2.

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

Итак, основной вопрос в том, кто устанавливает размер окна в 0 и где?
Где можно подключиться (в Инди?), Чтобы узнать, когда это условие происходит?

3 ответа

Решение

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

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

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

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

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

Поскольку вас может заинтересовать и решение вашей проблемы:

Если у вас есть какой-то контроль над тем, что работает на стороне сервера (тот, который отправляет сообщения с размером окна 0): Рассматривали ли вы использование setsockopt() с SO_RCVBUF, чтобы значительно увеличить размер буфера приема вашего сокета?

В Indy setsockopt() является методом TIdSocketHandle. Вы должны применить его ко всем объектам TIdSocketHandle, связанным с вашим сокетом. А в Indy 9 они расположены через свойство Bindings в вашем TIdTCPServer.

Я предлагаю сначала использовать getsockopt() с SO_RCVBUF, чтобы увидеть, что ОС дает вам в качестве размера буфера по умолчанию. Затем значительно увеличить это, возможно, путем последовательных испытаний, каждый раз удваивая размер. Возможно, вы также захотите повторно запустить вызов getsockopt() после вашего setsockopt(), чтобы убедиться, что ваш setsockopt действительно был выполнен: обычно существует верхний предел, который реализация сокета устанавливает для размеров буфера. И в этом случае обычно есть зависящий от ОС способ поднять это предельное значение. Но это довольно экстремальные случаи, и вам вряд ли это понадобится.

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

Удачи!

Другие вопросы по тегам