Работа с внешними ресурсами через протокол FTP в 1С — это стандартная задача, которая часто встречается при обмене данными с сайтами или государственными информационными системами. Однако разработчики нередко сталкиваются с ситуацией, когда процесс выгрузки файлов (особенно если их много) внезапно прерывается ошибкой «Ошибка работы с Интернет: ftp://... Превышено время ожидания». Эта проблема может проявляться хаотично: один раз выгрузка 1000 файлов проходит успешно, а в другой раз падает на десятом файле.
В этой статье мы подробно разберем причины возникновения этой ошибки, проанализируем поведение платформы 1С и сервера (на примере популярного FileZilla Server), а также выработаем пошаговую стратегию устранения неисправности.
Проанализируем типичную ошибку в коде, которую часто допускают начинающие разработчики. Если создавать новый объект FTPСоединение на каждой итерации цикла при записи файла, это приводит к колоссальной нагрузке на сетевой стек операционной системы.
Рассмотрим, почему это плохо. Каждое новое соединение требует выделения динамического порта (Ephemeral Port). После закрытия соединения порт не освобождается мгновенно, а переходит в состояние TIME_WAIT на несколько минут. Если файлов тысячи, порты в системе просто заканчиваются, и 1С выдает ошибку таймаута, так как не может открыть новый сокет.
Решение: Вынесем инициализацию соединения за пределы цикла. Разберем правильный пример кода:
// Неправильно:
Для Каждого Файл Из МассивФайлов Цикл
Соединение = Новый FTPСоединение("172.16.0.102", 21, "Логин", "Пароль");
Соединение.Записать(Файл.ПолноеИмя, Файл.Имя);
КонецЦикла;
// Правильно:
Соединение = Новый FTPСоединение("172.16.0.102", 21, "Логин", "Пароль", , Истина, 120);
Для Каждого Файл Из МассивФайлов Цикл
Попытка
Соединение.Записать(Файл.ПолноеИмя, Файл.Имя);
Исключение
ЗаписьЖурналаРегистрации("Ошибка FTP", УровеньЖурналаРегистрации.Ошибка, , , КраткоеОписаниеОшибки(ИнформацияОбОшибке()));
КонецПопытки;
КонецЦикла;
Многие ошибки «таймаута» связаны с тем, что 1С пытается работать в активном режиме, когда сервер инициирует обратное соединение с клиентом. В условиях современных корпоративных сетей, защищенных брандмауэрами и NAT, такие входящие пакеты часто блокируются, что приводит к зависанию и последующему обрыву по времени ожидания.
Выясним, как это исправить. При создании объекта FTPСоединение шестой параметр отвечает за пассивный режим. Мы рекомендуем всегда устанавливать его в значение Истина. В пассивном режиме клиент сам инициирует все соединения, что гораздо «дружелюбнее» к настройкам сетевой безопасности.
Пример конструктора с пассивным режимом:
Соединение = Новый FTPСоединение(АдресСервера, Порт, Логин, Пароль, Прокси, Истина, Таймаут);
В коде автора вопроса часто встречается установка таймаута в значение 0. В теории это означает «бесконечное ожидание», но на практике сетевые драйверы ОС или сама платформа 1С могут интерпретировать это значение некорректно, либо бесконечное ожидание приводит к «зависанию» сеанса без возможности восстановления.
Проанализируем ситуацию: если файл большой или канал связи нестабилен, стандартных 20–30 секунд может не хватить. Мы рекомендуем устанавливать явный таймаут в диапазоне 60–120 секунд. Это даст системе достаточный запас времени на подтверждение передачи пакетов сервером.
Если в качестве FTP-сервера используется FileZilla, стоит проверить настройки безопасности на стороне сервера. В этом программном продукте есть механизмы защиты, которые могут конфликтовать с интенсивной выгрузкой из 1С:
No Transfer Timeout и Connection Timeout. Если они установлены в слишком маленькие значения (например, 10 секунд), сервер сам будет обрывать связь, как только 1С возьмет небольшую паузу между обработкой файлов.Max connections. Если лимит исчерпан другими процессами, 1С не сможет подключиться.Хотя современная платформа 1С 8.3 неплохо работает с кодировками, передача имен файлов, содержащих русские буквы, иногда вызывает задержки или ошибки интерпретации команд сервером (команда STOR). Это может выглядеть как «подвисание» и последующий таймаут.
Разберем, как минимизировать риски. Если бизнес-процесс позволяет, лучше всего транслитерировать имена файлов перед отправкой на FTP. Если же это невозможно, убедитесь, что в настройках FTP-сервера принудительно включена поддержка UTF-8, а не используется системная кодировка (ANSI).
Если штатные средства 1С продолжают работать нестабильно (что бывает на очень плохих каналах связи), рассмотрим профессиональный подход — использование специализированных консольных утилит. Утилиты типа WinSCP или curl имеют гораздо более продвинутые алгоритмы обработки разрывов соединений и автоматического докачивания файлов.
Посмотрим на пример вызова WinSCP из кода 1С:
ПутьКПрограмме = "C:\Program Files (x86)\WinSCP\WinSCP.com";
Скрипт = "/command ""open ftp://user:password@172.16.0.102/"" ""put C:\LocalPath\File.xml /RemotePath/"" ""exit""";
ЗапуститьПриложение(ПутьКПрограмме + " " + Скрипт, , Истина);
Преимущество этого метода в том, что внешняя утилита работает в отдельном процессе и имеет собственные развитые настройки логирования, что позволяет точно выяснить причину сбоя, проанализировав лог-файл передачи.
Подводя итог нашему разбору, составим последовательность действий для устранения проблемы:
FTPСоединение за пределы цикла Для Каждого.ПассивныйРежим в конструкторе установлен в Истина.FileZilla Server.MTU и попробуйте отключить TCP Chimney Offload в Windows, если выгрузка идет на высоких скоростях.Применяя эти шаги, мы добьемся стабильной работы обмена данными и полностью устраним ошибки, связанные с превышением времени ожидания.