Winscp зависает при копировании

Обновлено: 04.07.2024

В определенный момент времени, от пользователя одной межрегиональной компании было получено обращение о довольно таки необычной и впервые мною наблюдаемой ошибке. В заявке отмечалось, что время от времени у клиента зависает копирование файлов по сети. Постепенно проблема эскалировалась на некоторое ограниченное количество других станции, при этом не приобретя характер эпидемии. По началу, описанная ситуация была зафиксирована в корпоративной сети между клиентскими рабочими станциями, функционирующими под управлением операционной системы Windows 7 и файловым сервером на Windows 2008R2. Зависание копирования файлов наблюдалось только для файлов, имеющих определенный размер, ориентировочно в диапазоне от 100 мегабайт и более, и визуально характеризовалось останавливающимся на произвольной отметке индикатором прогресса копирования и оценочной скоростью 0 байт/сек.:

Копирование файлов зависает

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

Проблема

Поначалу создалось впечатление, что в проблеме однозначно участвует файловый сервер Windows 2008R2, однако чуть позже, после более детального изучения инцидента стало очевидным, что зависает копирование файлов так же и между двумя произвольными клиентскими рабочими станциями, включенными в корпоративную локальную сеть. И в то же время, инцидент проявлял себя не часто и далеко не на всех машинах, было зафиксировано, что некоторые станции в корпоративной сети работали с тем же файловым сервером и между собой абсолютно нормально. При проявлении описанной проблемы сама система функционировала в штатном режиме, однако процесс explorer.exe , в контексте которого происходило копирование, зависал наглухо, зачастую не давая себя снимать через диспетчер задач. При этом, как минимум, протокол SMB переставал нормально функционировать, наблюдались проблемы с доступам к сетевым ресурсам. К тому же, в процессе выключения проблемной станции, этап завершения сеанса мог выполняться бесконечно долго. На основании обобщенного анализа всех деталей инцидента, можно было сделать вывод о достаточно сыром коде обработки различных нештатных ситуаций в стеке TCP/IP Windows 7, однако истинная причина крылась вовсе не в этом.
Как всегда, по началу применялся всеми горячо любимый, великий и могучий "метод тыка", обновлялись драйвера, сбрасывались настройки сетевого интерфейса, сравнивались установленные обновления, устраивались различные ритуальные танцы с бубном вокруг проблемных машин :), использовались и прочие, не менее действенные методы из арсенала технического специалиста. В итоге всего этого увлекательного действа виновник был найден, и им оказался сетевой маршрутизатор (располагающийся на пути следования пакетов данных), имеющий одну интересную особенность: прошивка не поддерживала динамическое окно передачи.

Теория

Перед нами встает резонный вопрос, что же это за динамическое окно передачи и какое влияние данная технология оказывает на процесс передачи файлов между хостами в сети? Применительно к протоколу TCP/IP определены такие понятия как окно приема TCP (TCP Receive Window, RWIN) и окно передачи TCP (TCP Send Window). В действительности это одно логическое окно, просто создается оно как на принимающей, так и на передающей сторонах при инициализации TCP соединения между двумя узлами сети, имеет на обеих сторонах одинаковую размерность, представляет из себя, фактически, типичный буфер (блок данных в памяти). Окно используется для контроля скорости потока принимающей стороной, а так же для указания количества данных, которые могут быть отправлены отправителем за один прием, оно так же определяет, какой объем неподтвержденных данных может находиться в пути от отправителя к получателю. Отправитель может посылать только байты передаваемого потока, находящиеся в данный момент внутри этого логического окна. Окно как бы перемещается по исходящему байтовому потоку данных на отправляющей стороне и входящему байтовому потоку данных на принимающей стороне. Выражаясь яснее, участок данных в исходящем байтовом потоке, который отправителю разрешено отправлять, соответствует участку данных во входящем байтовом потоке, который получатель может принять.

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

Технология масштабирования окна TCP ( TCP Window Scaling ), описанная в предложении RFC 1323, была реализована разработчиками впервые еще в сетевом стеке TCP/IP операционной системы Windows 2000, но по-умолчанию предусмотрительно была отключена. В версиях Windows, предшествующих Vista, окно приема TCP имело максимальный размер, равный 64 килобайта (65535 байт). Начиная с Windows Vista разработчики модифицировали стек TCP/IP и реализовали алгоритм автоматической настройки окна приема TCP ( TCP Receive Window Auto-Tuning ), который использует TCP Window Scaling Option. Теперь уже окно приема TCP, за счет введения дополнительной опции в заголовке TCP пакета, может расширяться аж до 16 мегабайт. Алгоритм TCP Receive Window Auto-Tuning позволяет ядру определять оптимальный размер окна приема TCP на основании измерения интегрального показателя задержки передачи и скорости извлечения данных принимающим приложением, после чего размер окна адаптируется (в реальном времени) в соответствии с изменяющимися параметрами физического канала передачи и приложения. Во время передачи данных в рамках TCP-сессии обе стороны стараются установить оптимальный размер данного окна для повышения производительности обмена данными через каналы с высокой пропускной способностью и высоким показателем задержки передачи, к коим и относится большинство современных каналов сети Интернет.

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

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

Решение

Для решения проблемы зависания копирования файлов по сети к нам на выручку приходит системная утилита командной строки netsh , предназначенная для управления параметрами сетевой конфигурации локальной или удаленной станции.

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

Давайте посмотрим текущее состояние некоторых параметров настройки интерфейса TCP/IP, выполнив следующую команду:

netsh interface tcp show global

В ответ мы получили вывод текущих параметров настройки TCP/IP, среди которых нас интересует "Уровень автонастройки окна получения", который по-умолчанию имеет значение "normal":

зависает копирования файлов

Параметр может принимать следующие значения:

  • disabled предписывает использовать фиксированное значение окна приема TCP. Значение по-умолчанию = 64 килобайта (65535 байт). Полная совместимость со устаревшим сетевым оборудованием;
  • highlyrestricted позволяет окну приема TCP выходить за границы значения по-умолчанию, в разумных пределах;
  • restricted позволяет окну приема TCP выходить за границы значения по-умолчанию, еще более свободно;
  • normal установка по умолчанию. Допускает увеличение окна приема TCP с учетом большинства возможных сценариев обмена;
  • experimental позволяет окну приема TCP увеличиваться до максимальных значений (16+ мегабайт). Не рекомендуется, потому как может вызвать падение производительности в большинстве возможных сценариев обмена;
После применения нижеописанных команд потребуется перезагрузка операционной системы.

Для начала переводим уровень автонастройки окна получения в значение disabled , фактически отключая автонастройку и предписывая использование фиксированного значения:

netsh interface tcp set global autotuninglevel=disabled

Вышеприведенная команда полностью устраняет зависание копирования файлов, однако, опционально, я бы рекомендовал выполнить еще и следующую.
Следующая команда отключает масштабирование на принимающей стороне (receive-side scaling), которое распределяет сетевую нагрузку между несколькими ядрами процессора в многопроцессорной системе:

netsh interface tcp set global rss=disabled

Выводы

В ситуации, когда обмен данными происходит между двумя, напрямую подключенными друг к другу, станциями под управлением операционных систем Windows версий Vista и более поздних, проблема никогда себя не обнаруживает. Однако в современной корпоративной сетевой среде довольно часто применяются управляемые коммутаторы и прочие сложные сетевые устройства, и вот именно их собратья с устаревшим микропрограммным обеспечением, не поддерживающие динамическое окно передачи, и становятся источником проблемы зависания копирования файлов (и ряда смежных). Конкретно в нашем случае виновником был Cisco Catalyst 3750 v2 с версией Cisco IOS Software младше 12.3(15). В дополнение к данной конфигурации, теоретически ошибка может проявляться при передаче между двумя станциями, подключенными напрямую, одна из которых работает под управлением Windows версии Vista и более поздних, а другая под управлением старых операционных систем (таких как Windows XP и более ранних), однако я лично подобную связку не тестировал.

Читайте также: