При интеграции электронного торгового оборудования с системой «1С:Предприятие» специалисты часто сталкиваются с нестандартным поведением драйверов в распределенных сетях. Типичный пример — работа с весами или терминалами сбора данных «Масса-К». В локальном сегменте сети (когда сервер 1С и весы находятся в одной подсети) обмен данными проходит мгновенно и без ошибок. Однако стоит разнести устройства по разным подсетям (например, связать склад и офис через маршрутизатор или VPN-туннель), как начинается странное поведение: при выгрузке или загрузке данных возвращаемый драйвером XML-пакет стабильно обрезается в одном и том же месте.
В этой статье мы подробно разберем, почему возникает эта проблема, проанализируем физику сетевых процессов и предложим пошаговые инструкции по ее устранению.
Давайте разберем механизм вызова программного интерфейса драйвера. В коде 1С вызов стандартного метода выгрузки выглядит следующим образом:
// Вызов метода загрузки товаров в весы через стандартный драйвер
Результат = Драйвер.ЗагрузитьТовары(ИдУстройства, XMLТаблицаТоваров);
При этом переменная XMLТаблицаТоваров передается по ссылке, и в нее должен записаться ответный XML-документ от весов. В случае успешного выполнения в локальной сети мы получаем валидную структуру XML. Но в распределенной сети структура оказывается незавершенной (отсутствуют закрывающие теги, строка обрывается на полуслове), из-за чего парсер 1С выдает ошибку чтения XML.
Выясним истинную причину этого явления. Здесь сходятся две проблемы — особенности реализации сетевого кода в самом драйвере «Масса-К» и специфика прохождения TCP-трафика через маршрутизаторы.
1. Особенности работы TCP-сокетов в драйвере весов
Протокол TCP является потоковым (Stream-oriented), а не пакетным. Это означает, что данные передаются непрерывным потоком байтов, который на физическом уровне нарезается операционной системой на отдельные IP-пакеты. Когда программа отправляет большой XML-файл, принимающая сторона должна считывать данные из сокета в цикле до тех пор, пока не встретит маркер конца данных (или закрывающий тег </Table>, или пока соединение не закроется удаленным узлом).
В локальной сети сетевые задержки (RTT) стремятся к нулю. Весь XML-пакет весов физически «долетает» до сетевого буфера компьютера мгновенно. Драйвер весов (например, библиотека MassaKDriverR1C.dll) делает один системный вызов чтения из сокета и сразу забирает весь объем данных.
В разных подсетях (особенно при связи через интернет или VPN) задержки возрастают. Пакеты идут с микрозадержками. Если код драйвера написан упрощенно — например, ожидает данные по таймауту или делает однократный вызов чтения без контроля целостности XML-структуры, — то он забирает только то, что успело прийти в первом TCP-окне (обычно около 1460 байт). Остальная часть данных, задержавшаяся в пути на несколько миллисекунд, просто отбрасывается драйвером, и в 1С возвращается «обрезанный» кусок.
2. Проблема размера MTU и фрагментации пакетов
Стандартный размер максимального блока передачи (MTU) в сетях Ethernet равен 1500 байт. Из них 40 байт уходит на заголовки IP и TCP, оставляя 1460 байт под чистые данные (MSS — Maximum Segment Size).
Если ваши подсети А и Б связаны через VPN-туннель (IPsec, OpenVPN, WireGuard, GRE), то к пакету добавляются дополнительные служебные заголовки шифрования и инкапсуляции. В результате эффективный MTU внутри туннеля падает до 1400–1450 байт.
Если маршрутизатор получает пакет размером 1500 байт, который нужно отправить в туннель с MTU 1400, он должен либо фрагментировать его (разбить на два), либо отбросить. Если на сетевом оборудовании или брандмауэре заблокировано прохождение служебных ICMP-сообщений (в частности, Type 3, Code 4 — «Fragmentation Needed»), механизм автоматического определения пути Path MTU Discovery (PMTUD) ломается. Пакет просто уничтожается («черная дыра» маршрутизации), соединение зависает, а драйвер 1С по таймауту возвращает лишь ту часть данных, которая успела проскочить.
3. Глубокий анализ пакетов брандмауэрами (DPI / IPS)
Современные межсетевые экраны, контролирующие трафик между внутренними подсетями предприятия, могут расценивать передачу нешифрованного XML-текста большого объема по нестандартным портам (весы «Масса-К» по умолчанию используют порт 5001) как попытку атаки (например, переполнение буфера или внедрение кода). Система предотвращения вторжений (IPS) может принудительно разрывать сессию прямо посреди трансляции данных.
---
Прежде чем приступать к изменению настроек оборудования, давайте точно определим, виновата ли фрагментация пакетов (MTU). Для этого воспользуемся встроенной консольной утилитой операционной системы.
Откроем командную строку на компьютере в подсети А (где установлена 1С) и запустим пинг до весов в подсети Б с запретом фрагментации пакета и указанием размера буфера. Начнем со стандартного размера:
ping 192.168.2.15 -f -l 1472
Параметр -f указывает сетевому стеку установить флаг «Do not fragment» (не фрагментировать), а -l 1472 задает размер полезной нагрузки (1472 байта + 28 байт заголовков ICMP/IP дают ровно 1500 байт).
Если в ответ мы получаем сообщение «Требуется фрагментация пакета, но установлен запрет» или просто потерю пакетов по таймауту, значит, на пути прохождения трафика есть узкое горлышко.
Начнем последовательно уменьшать размер буфера, пока не найдем точное пороговое значение, при котором пакеты начнут проходить без потерь:
ping 192.168.2.15 -f -l 1420
ping 192.168.2.15 -f -l 1372
Если пакеты начинают стабильно проходить, например, только на значении 1372 (что соответствует общему MTU 1400), мы нашли корень проблемы. Сетевое оборудование режет пакеты драйвера весов, превышающие этот размер.
---
Наиболее правильный и системный способ решения проблемы фрагментации в маршрутизируемых сетях — это принудительное изменение размера сегмента TCP (MSS Clamping) на пограничных устройствах (роутерах), связывающих подсети.
Этот механизм перехватывает служебные пакеты SYN при установлении TCP-соединения между ПК и весами и принудительно заменяет заявляемый устройствами размер MSS на меньший (соответствующий реальному MTU туннеля). В результате сетевые карты весов и сервера сразу начинают отправлять пакеты уменьшенного размера, которые гарантированно проходят через любые шлюзы без фрагментации.
Рассмотрим, как это настраивается на примере популярного оборудования MikroTik. Вам необходимо добавить правило в таблицу Firewall Mangle через веб-интерфейс или терминал:
/ip firewall mangle
add chain=forward action=change-mss new-mss=clamp-to-pmtu passthrough=yes tcp-flags=syn protocol=tcp out-interface=all-vlan
Или жестко задать ограничение размера MSS до безопасного значения (например, до 1360 байт, что отлично подходит для большинства VPN-соединений):
/ip firewall mangle
add chain=forward action=change-mss new-mss=1360 passthrough=no tcp-flags=syn protocol=tcp in-interface=vpn-tunnel
На межсетевых экранах других производителей (Cisco, FortiGate, pfSense) аналогичная функция называется TCP MSS Adjustment или MSS Clamping. Включите ее для интерфейсов, через которые связаны подсети А и Б.
---
Если архитектура вашей корпоративной сети позволяет внести изменения в адресацию, либо если решить проблему на уровне маршрутизации L3 не удается из-за ограничений провайдера связи, можно пойти путем логического объединения подсетей.
Вариант А: Изменение маски подсети (подходит для одной физ. площадки)
Если подсети А и Б находятся в пределах одного здания и разделены маршрутизатором просто «исторически», можно расширить адресное пространство, изменив маску подсети со стандартной 255.255.255.0 (маска /24) на более широкую 255.255.0.0 (маска /16).
Например, если компьютер имел IP 192.168.1.50, а весы — 192.168.2.15, то при маске 255.255.255.0 они находились в разных сетях и трафик шел через шлюз. При установке на обоих устройствах маски 255.255.0.0 они окажутся в одной логической сети 192.168.0.0/16. Обмен пойдет напрямую на уровне L2 (Ethernet-кадры), минуя таблицы маршрутизации роутера, что полностью устранит задержки и проблему фрагментации.
Вариант Б: Использование L2 VPN (для удаленных филиалов)
Если подсети географически распределены, перенастройте тип VPN-соединения с L3 (маршрутизируемый туннель, например, стандартный IPsec или OpenVPN в режиме TUN) на L2 (сетевой мост, например, EoIP у MikroTik, или OpenVPN в режиме TAP).
Это позволит объединить удаленные порты коммутаторов в один виртуальный сегмент. Весы «Масса-К» физически будут находиться на удаленном складе, но системный администратор сможет выдать им IP-адрес из той же подсети, в которой находится сервер 1С. Для драйвера весов это будет выглядеть как прямое локальное подключение.
---
Зачастую старые версии драйверов «Масса-К» (например, компоненты серий 6.х или 7.х) используют устаревшие библиотеки сокетов с жестко зашитыми внутренними таймаутами чтения. При задержке пакета хотя бы на 10-15 мс драйвер считает, что передача завершена, и отдает в 1С недогруженный буфер.
Для исправления этой проблемы выполним следующие действия:
После установки нового драйвера зайдем в настройки торгового оборудования в 1С и увеличим параметр «Таймаут соединения» (Connection Timeout) с дефолтных 1000 мс до 5000–8000 мс. Это даст драйверу запас времени на сборку всех приходящих TCP-сегментов в единый буфер перед передачей его в платформу 1С.