При интеграции 1С с внешними сервисами, торговым оборудованием или распределенными базами данных часто возникает необходимость заранее проверить, доступен ли удаленный хост по заданному порту. Обычный ping (протокол ICMP) позволяет лишь узнать, отвечает ли сам сервер, но не дает информации о доступности конкретной службы (TCP-порта), работающей на нем.
В платформе 1С:Предприятие отсутствует встроенный низкоуровневый объект для произвольной работы с "сырыми" TCP/UDP-сокетами. Однако решить задачу проверки доступности порта можно несколькими практическими способами в зависимости от контекста выполнения, используемой операционной системы и типа опрашиваемого сервиса. Разберем эти варианты подробно.
Если на целевом порту работает веб-сервис или любой сервис, отвечающий по протоколам HTTP/HTTPS, наиболее простым и быстрым решением является использование штатного объекта HTTPСоединение. Параметр сервера может принимать как доменное имя, так и IP-адрес.
Рассмотрим, как реализовать такую проверку с контролем таймаута:
Функция ПроверитьДоступностьHTTPПорта(Знач Хост, Знач Порт, Знач Таймаут = 3)
Попытка
// Создаем соединение с указанным таймаутом в секундах
Соединение = Новый HTTPСоединение(Хост, Порт, , , , Таймаут);
Запрос = Новый HTTPЗапрос("/");
Ответ = Соединение.Получить(Запрос);
Возврат Истина;
Исключение
// Если сервис сбросил соединение или не ответил по таймауту
Возврат Ложь;
КонецПопытки;
КонецФункции
Нюанс использования: данный метод отлично подходит для веб-серверов, REST API и HTTP-сервисов. Однако если на порту работает служба, не использующая протокол HTTP (например, СУБД или специализированное торговое оборудование), она может мгновенно разорвать соединение при получении невалидного HTTP-запроса, что вызовет исключение в блоке Попытка...Исключение, даже если сетевой порт фактически открыт.
Для универсальной проверки любого TCP-порта в среде Windows наиболее надежным способом является запуск системного командлета Test-NetConnection. Этот метод позволяет проверить именно установку TCP-сессии без привязки к прикладному протоколу.
Разберем по шагам создание функции с сохранением и чтением результата через временный файл:
Функция ПроверитьПортWindows(Знач Хост, Знач Порт)
ИмяВременногоФайла = ПолучитьИмяВременногоФайла("txt");
// Формируем команду PowerShell, возвращающую True или False
Команда = СтрШаблон("powershell -Command ""(Test-NetConnection -ComputerName '%1' -Port %2 -InformationLevel Quiet)"" > ""%3""",
Хост, Формат(Порт, "ЧГ=0"), ИмяВременногоФайла);
// Запускаем процесс в скрытом режиме с ожиданием завершения
ЗапуститьПриложение(Команда, , Истина);
Результат = Ложь;
ФайлРезультата = Новый Файл(ИмяВременногоФайла);
Если ФайлРезультата.Существует() Тогда
ТекстовыйФайл = Новый ЧтениеТекста(ИмяВременногоФайла, КодировкаТекста.ANSI);
ТекстОтвета = СокрЛП(ТекстовыйФайл.ПрочитатьСтроку());
ТекстовыйФайл.Закрыть();
УдалитьФайлы(ИмяВременногоФайла);
Если ВРег(ТекстОтвета) = "TRUE" Тогда
Результат = Истина;
КонецЕсли;
КонецЕсли;
Возврат Результат;
КонецФункции
Если сервер 1С работает под управлением Linux, использование PowerShell или COM-технологий невозможно. В этом случае проанализируем доступность порта с помощью стандартных утилит nc (netcat) или функционала сокетов оболочки bash.
Посмотрим на пример проверки с помощью метода ЗапуститьПриложение, анализируя код возврата программы:
Функция ПроверитьПортLinux(Знач Хост, Знач Порт, Знач Таймаут = 2)
// Утилита nc с ключом -z (zero-I/O mode) и таймаутом -w
Команда = СтрШаблон("nc -z -w %1 %2 %3", Таймаут, Хост, Формат(Порт, "ЧГ=0"));
КодВозврата = 0;
ЗапуститьПриложение(Команда, , Истина, КодВозврата);
// При успешном подключении nc возвращает 0
Возврат (КодВозврата = 0);
КонецФункции
В случаях, когда требуется выполнять частые проверки большого пула адресов без накладных расходов на создание системных процессов ОС, разберем альтернативные варианты:
MSWinsock.Winsock, однако в современных 64-разрядных средах и на Linux-серверах данный подход считается устаревшим и платформозависимым.Выясним частые причины, по которым проверка порта может выдавать некорректный результат:
&НаСервере, опрос инициируется сервером 1С. Если же код запущен на клиенте, проверка идет с рабочего места пользователя. Сетевые маршруты, списки контроля доступа (ACL) и настройки брандмауэра для них могут существенно различаться.127.0.0.1 (localhost), из-за чего внешние подключения по локальному IP-адресу сети будут отклоняться.