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

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

В процессе интеграции 1С с внешними сервисами, базами данных, торговым оборудованием или фискальными регистраторами часто требуется предварительно проверить, доступен ли конкретный сетевой узел и открыт ли на нем целевой порт. Выясним причину сложностей реализации такой проверки: во встроенном языке 1С отсутствуют низкоуровневые объекты для прямой работы с «сырыми» сокетами (Raw TCP/UDP Sockets). Однако задачу можно эффективно решить несколькими способами в зависимости от операционной системы и типа используемого протокола.

Разберем основные практические методы сканирования и проверки портов.

Способ 1. Использование встроенного объекта HTTPСоединение (для веб-сервисов)

Если проверяемый порт предназначен для работы по протоколам HTTP/HTTPS (например, веб-сервисы, REST API, веб-серверы Apache/IIS), наиболее надежным и кроссплатформенным решением является встроенный объект HTTPСоединение. Посмотрим на пример кода с контролем таймаута:


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

Преимущество метода: работает как на Windows, так и на Linux-серверах без вызова внешних процессов и зависимостей.

Способ 2. Проверка через PowerShell и утилиты ОС (Windows)

Рассмотрим вариант проверки произвольного TCP-порта на удаленном хосте в среде Windows. Для этого можно вызвать команду PowerShell через метод платформы ЗапуститьПриложение и проанализировать код возврата или результат выполнения команды.

Разберем по шагам вызов командлета Test-NetConnection:

  1. Формируем команду проверки подключения к хосту и порту с флагом -InformationLevel Quiet (возвращает True или False).
  2. Вызываем утилиту через команду powershell.exe.
  3. Для получения целочисленного кода возврата можно также использовать вызов метода TcpClient.Connect.

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


Функция ПроверитьПортPowerShell(Хост, Порт, ТаймаутСек = 3) Экспорт
    Команда = СтрШаблон("powershell -Command ""$client = New-Object System.Net.Sockets.TcpClient; $iar = $client.BeginConnect('%1', %2, $null, $null); $wait = $iar.AsyncWaitHandle.WaitOne(%3000, $false); if($wait -and $client.Connected){ $client.EndConnect($iar); $client.Close(); exit 0 } else { exit 1 }""", Хост, Формат(Порт, "ЧГ="), ТаймаутСек);
    
    КодВозврата = -1;
    ЗапуститьПриложение(Команда, , Истина, КодВозврата);
    
    Возврат (КодВозврата = 0);
КонецФункции

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

Если сервер 1С функционирует под управлением ОС Linux, вызов PowerShell неприменим. Проанализируем ситуацию в среде Linux: для проверки портов используются стандартные утилиты nc (Netcat) или встроенные возможности командного интерпретатора bash.


Функция ПроверитьПортLinux(Хост, Порт, ТаймаутСек = 2) Экспорт
    // Использование встроенного сетевого псевдоустройства bash с ограничением по времени
    Команда = СтрШаблон("timeout %1 bash -c 'cat < /dev/null > /dev/tcp/%2/%3'", ТаймаутСек, Хост, Формат(Порт, "ЧГ="));
    
    КодВозврата = -1;
    ЗапуститьПриложение(Команда, , Истина, КодВозврата);
    
    Возврат (КодВозврата = 0);
КонецФункции

Способ 4. Использование COM-объекта Winsock (только Windows)

Рассмотрим альтернативный способ для устаревших Windows-систем с использованием компонента MSWINSOCK.Winsock.1. Данный метод работает синхронно в цикле ожидания изменения состояния сокета.


Функция СканироватьПортWinsock(Хост, Порт) Экспорт
    Результат = Ложь;
    Попытка
        Сокет = Новый COMОбъект("MSWINSOCK.Winsock.1");
        Сокет.RemoteHost = Хост;
        Сокет.RemotePort = Порт;
        Сокет.Connect();
        
        Счетчик = 0;
        // Состояние 7 означает успешное подключение (sckConnected)
        Пока Сокет.State <> 7 И Счетчик < 20 Цикл
            Приостановить(0.1);
            Счетчик = Счетчик + 1;
        КонецЦикла;
        
        Если Сокет.State = 7 Тогда
            Результат = Истина;
            Сокет.Close();
        КонецЕсли;
    Исключение
        Результат = Ложь;
    КонецПопытки;
    
    Возврат Результат;
КонецФункции

Важные сетевые особенности при проверке портов

При реализации сетевой проверки важно учитывать технические нюансы работы сетевого стека:

  1. Разница между закрытым и фильтруемым портом: Если порт закрыт, но узел работает, операционная система хоста мгновенно отправляет ответный пакет TCP RST (сброс соединения). Если же пакеты блокируются фаерволом (DROP), ответ не возвращается, и процесс ожидает ответа до истечения системного или заданного таймаута.
  2. Блокировка потока интерфейса: Все сетевые вызовы с ожиданием ответа необходимо выносить в фоновые задания с помощью объекта ФоновыеЗадания.Выполнить, чтобы не вызывать зависания интерфейса клиентского приложения 1С.
  3. Специфика UDP-портов: Описанные выше методы сокетов ориентированы на TCP-соединения с трехсторонним рукопожатием. Для UDP-протокола проверка доступности порта без отправки специфических для конкретного сервиса данных не дает гарантированного результата.
← На главную