Как в 1С проверить доступность порта на удаленном компьютере

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При интеграции 1С с внешними сервисами, торговым оборудованием или распределенными базами данных часто возникает необходимость заранее проверить, доступен ли удаленный хост по заданному порту. Обычный ping (протокол ICMP) позволяет лишь узнать, отвечает ли сам сервер, но не дает информации о доступности конкретной службы (TCP-порта), работающей на нем.

В платформе 1С:Предприятие отсутствует встроенный низкоуровневый объект для произвольной работы с "сырыми" TCP/UDP-сокетами. Однако решить задачу проверки доступности порта можно несколькими практическими способами в зависимости от контекста выполнения, используемой операционной системы и типа опрашиваемого сервиса. Разберем эти варианты подробно.

Способ 1. Проверка через объект HTTPСоединение

Если на целевом порту работает веб-сервис или любой сервис, отвечающий по протоколам HTTP/HTTPS, наиболее простым и быстрым решением является использование штатного объекта HTTPСоединение. Параметр сервера может принимать как доменное имя, так и IP-адрес.

Рассмотрим, как реализовать такую проверку с контролем таймаута:


Функция ПроверитьДоступностьHTTPПорта(Знач Хост, Знач Порт, Знач Таймаут = 3)
    Попытка
        // Создаем соединение с указанным таймаутом в секундах
        Соединение = Новый HTTPСоединение(Хост, Порт, , , , Таймаут);
        Запрос = Новый HTTPЗапрос("/");
        Ответ = Соединение.Получить(Запрос);
        Возврат Истина;
    Исключение
        // Если сервис сбросил соединение или не ответил по таймауту
        Возврат Ложь;
    КонецПопытки;
КонецФункции

Нюанс использования: данный метод отлично подходит для веб-серверов, REST API и HTTP-сервисов. Однако если на порту работает служба, не использующая протокол HTTP (например, СУБД или специализированное торговое оборудование), она может мгновенно разорвать соединение при получении невалидного HTTP-запроса, что вызовет исключение в блоке Попытка...Исключение, даже если сетевой порт фактически открыт.

Способ 2. Проверка через PowerShell (для серверов и клиентов под Windows)

Для универсальной проверки любого TCP-порта в среде Windows наиболее надежным способом является запуск системного командлета Test-NetConnection. Этот метод позволяет проверить именно установку TCP-сессии без привязки к прикладному протоколу.

Разберем по шагам создание функции с сохранением и чтением результата через временный файл:


Функция ПроверитьПортWindows(Знач Хост, Знач Порт)
    ИмяВременногоФайла = ПолучитьИмяВременногоФайла("txt");
    
    // Формируем команду PowerShell, возвращающую True или False
    Команда = СтрШаблон("powershell -Command ""(Test-NetConnection -ComputerName '%1' -Port %2 -InformationLevel Quiet)"" > ""%3""", 
        Хост, Формат(Порт, "ЧГ=0"), ИмяВременногоФайла);
    
    // Запускаем процесс в скрытом режиме с ожиданием завершения
    ЗапуститьПриложение(Команда, , Истина);
    
    Результат = Ложь;
    ФайлРезультата = Новый Файл(ИмяВременногоФайла);
    Если ФайлРезультата.Существует() Тогда
        ТекстовыйФайл = Новый ЧтениеТекста(ИмяВременногоФайла, КодировкаТекста.ANSI);
        ТекстОтвета = СокрЛП(ТекстовыйФайл.ПрочитатьСтроку());
        ТекстовыйФайл.Закрыть();
        УдалитьФайлы(ИмяВременногоФайла);
        
        Если ВРег(ТекстОтвета) = "TRUE" Тогда
            Результат = Истина;
        КонецЕсли;
    КонецЕсли;
    
    Возврат Результат;
КонецФункции

Способ 3. Проверка через утилиты командной строки Linux

Если сервер 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);
КонецФункции

Способ 4. Использование внешних компонент (Native API) или COM-объектов

В случаях, когда требуется выполнять частые проверки большого пула адресов без накладных расходов на создание системных процессов ОС, разберем альтернативные варианты:

  1. Внешние компоненты Native API: подключение скомпилированной кроссплатформенной библиотеки (написанной на C++ или Rust), которая реализует метод проверки соединения через стандартные системные сокеты Беркли. Это самый быстрый и ресурсоэффективный способ.
  2. COM-объекты Windows: на 32-разрядных платформах Windows ранее применялся объект MSWinsock.Winsock, однако в современных 64-разрядных средах и на Linux-серверах данный подход считается устаревшим и платформозависимым.

Важные нюансы сетевой диагностики

Выясним частые причины, по которым проверка порта может выдавать некорректный результат:

  1. Различие сетевого контекста (Клиент против Сервера): если проверка выполняется в модуле с директивой &НаСервере, опрос инициируется сервером 1С. Если же код запущен на клиенте, проверка идет с рабочего места пользователя. Сетевые маршруты, списки контроля доступа (ACL) и настройки брандмауэра для них могут существенно различаться.
  2. Привязка службы к интерфейсу: удаленный сервис может быть успешно запущен, но "слушать" только локальный интерфейс 127.0.0.1 (localhost), из-за чего внешние подключения по локальному IP-адресу сети будут отклоняться.
  3. Поведение файрвола (DROP против REJECT): если межсетевой экран настроен на сброс пакетов (DROP), проверка завершится только после истечения полного времени таймаута. Если настроен явный отказ (REJECT/TCP RST), статус недоступности возвращается мгновенно.
← На главную