Russian Qt Forum
Ноябрь 23, 2024, 22:29
Добро пожаловать,
Гость
. Пожалуйста,
войдите
или
зарегистрируйтесь
.
Вам не пришло
письмо с кодом активации?
1 час
1 день
1 неделя
1 месяц
Навсегда
Войти
Начало
Форум
WIKI (Вики)
FAQ
Помощь
Поиск
Войти
Регистрация
Russian Qt Forum
>
Forum
>
Программирование
>
Общий
>
Modbus/TCP ошибочный пакет
Страниц: [
1
]
Вниз
« предыдущая тема
следующая тема »
Печать
Автор
Тема: Modbus/TCP ошибочный пакет (Прочитано 8563 раз)
juvf
Программист
Offline
Сообщений: 570
Modbus/TCP ошибочный пакет
«
:
Июль 15, 2009, 14:08 »
Ктонибудь реализовывал протокол Modbus/TCP? Что делать слэйву, если пакет с ошибкой?
В Modbus RTU всё понятно. Если адрес не тот, или CRC не совпал, то молчим. А если не то значение или не допустимые данные, то отвечаем исключением. А как в Modbus/TCP ?
В спецификации протокола MODBUS/TCP описан следующий формат:
Цитировать
Запрос и ответ предваряются шестью следующими байтами:
байт 0: идентификатор транзакции – копируется сервером – обычно 0
байт 1: идентификатор транзакции – копируется сервером – обычно 0
байт 2: идентификатор протокола = 0
байт 3: идентификатор протокола = 0
байт 4: поле длины (старший байт) = 0 (так как все сообщения меньше 256)
байт 5: поле длины (младший байт) = количество следующих байтов
байт 6: идентификатор устройства (раньше «адрес SLAVE»)
байт 7: код функции MODBUS
байт 8: данные, если требуется
Существует транспорто-зависимый префикс, который в случае MODBUS/TCP включает в себя семь байт:
ref ref 00 00 00 len unit
«ref ref» – два байта «смещения транзакции» - число, которое не имеет значения на сервере, но копируется дословно от запроса к ответу для удобства клиента. Простые клиенты обычно оставляют эти значения нулевыми.
Слэйв получит пакет по TCP, в котором транспорто-зависимый префикс будет с ошибкой, например идентификатор протокола не будет равен 0, или поле длины будет равно 1234, при допустимом 255 - что делать? Разрывать соединение? или игнорировать пакет(молчать), или ответить исключением с кодом ошибки?
Записан
kuzulis
Джедай : наставник для всех
Offline
Сообщений: 2812
Re: Modbus/TCP ошибочный пакет
«
Ответ #1 :
Июль 15, 2009, 16:05 »
Цитировать
А если не то значение или не допустимые данные, то отвечаем исключением. А как в Modbus/TCP ?
аналогично
см п 4.4.2.1 в MODBUS Messaging on TCP/IP Implementation Guide V1.0b
Записан
ArchLinux x86_64 / Win10 64 bit
kuzulis
Джедай : наставник для всех
Offline
Сообщений: 2812
Re: Modbus/TCP ошибочный пакет
«
Ответ #2 :
Июль 15, 2009, 16:14 »
вот еще:
---
Операционные системы и языки программирования, которые
поддерживают многопоточность, например JAVA, могут использовать
многопоточную стратегию, описанную здесь:
Используйте listen() для ожидания входящего соединения на TCP порт
502. Когда запроса нового соединения получен, используйте accept()
для его подтверждения и создайте новый поток для управления
соединением.
В новом потоке выполняйте следующий бесконечный цикл:
Выдайте recv(6) запрос для 6 байт MODBUS/TCP заголовка. Не
выставляйте здесь время ожидания, а ожидайте, пока запрос не
пройдет или соединение не закроется. Обе ситуации автоматически
известят поток.
Проанализируем заголовок. Если он окажется нарушенным, например,
поле протокола ненулевое или длина сообщения более 256, тогда в
одностороннем порядке закройте соединение. Это надлежащий ответ
сервера, если возникла ситуация, предполагающая неправильное TCP
кодирование.
Выдайте recv() для оставшихся байтов сообщения, длина которых
известна. Помните, что в отдельных случаях, при выдаче recv() с
подобным ограничением по длине допускает клиентов, требующих
«конвейерных» запросов. Любые подобные конвейерные запросы будут
оставаться в буферах TCP сервера или клиента, и будут обработаны
позже, когда существующие запросы завершатся.
Теперь обработайте входящее MODBUS сообщение, если необходимо,
приостановив текущий поток, пока правильный ответ не будет
подсчитан. В итоге у вас будет либо действительное MODBUS
сообщение или сообщение исключения EXCEPTION для использования в
качестве ответа.
Сформируйте MODBUS/TCP префикс для ответа, путем копирования байт
0 и 1 поля «идентификатора транзакции» запроса, и пересчитав длину
поля. Подтвердите ответ, включая MODBUS/TCP префикс, как один
буфер для передачи по соединению, используя send()
Вернитесь и ждите следующих 6 байт префикса записи.
В конечном счете, когда клиент решит закрыть соединение, команда
recv() 6 байт префикса не сработает. Правильное закрытие обычно
возвращает в команде recv() нулевое количество байт.
Принудительное закрытие может вызвать ошибочный результат команды
recv(). В любом случае, закройте соединение и существующий поток.
----
Записан
ArchLinux x86_64 / Win10 64 bit
juvf
Программист
Offline
Сообщений: 570
Re: Modbus/TCP ошибочный пакет
«
Ответ #3 :
Июль 16, 2009, 07:03 »
Цитата: kuzulis
Проанализируем заголовок. Если он окажется нарушенным, например,
поле протокола ненулевое или длина сообщения более 256, тогда в
одностороннем порядке закройте соединение. Это надлежащий ответ
сервера, если возникла ситуация, предполагающая неправильное TCP
Это приложение спецификации OPEN MODBUS/TCP SPECIFICATION от 1999 года, в которой не оговариваются чёткие рамки, а просто предлагается некая реализация сервера.
Однко в MODBUS Messaging on TCP/IP Implementation Guide V1.0b от 2006 года говорится
Цитировать
The MODBUS PDU Checking function consists of first parsing the MBAP Header. The Protocol Identifier field has to be checked :
If it is different from MODBUS protocol type, the indication is simply discarded.
is simply discarded
- я это понял так "просто бракуется (отвергается)". Т.е. если в транспорто-зависимом префиксе (заголовоке) ошибка, то соединение не разрывается, а просто эта посылка бракуется, игнорируется.
ps Но мне кажется, что разорвать соединение - это более правильно. имхо. Дилемма ((
Записан
kuzulis
Джедай : наставник для всех
Offline
Сообщений: 2812
Re: Modbus/TCP ошибочный пакет
«
Ответ #4 :
Июль 16, 2009, 07:51 »
Цитировать
ps Но мне кажется, что разорвать соединение - это более правильно. имхо. Дилемма ((
Ну да! Я тож считаю что так и нужно делать (разрывать), т.к PID отличный от нуля НЕ есть PID модбаса - а PID како-го то иного протокола.. а ваш сервер ведь МОДБАС! так какой ему резон поддерживать подключение - если ему шлют НЕ МОДБАС ADU !
т.е. нужно рвать..
ЗЫ: Вы когда слышите уругвайское наречие - вы разве пытаетесь понять что там говорят? НЕТ! Вы просто говорите им : "пошли Вы нафик"
Записан
ArchLinux x86_64 / Win10 64 bit
alex12
Гость
Re: Modbus/TCP ошибочный пакет
«
Ответ #5 :
Июль 20, 2009, 23:39 »
Я много работал и программировал Modbus. И RTU и TCP.
Мое мнение: если пакет ошибочен -- сразу надо разрывать связь (закрывать сокет). Ошибочный пакет - значит все - что-то накрылось. Где-то произошел сбой и единственный метод разрулить эту ситуацию - закрыть сокет.
Еще интересный момент: тайм-аут. Сам TCP не отслеживает ситуацию, когда пакеты просто перестали идти. Напритер где-то накрылся канал. Открытый TCP сокет на сервере будет бесконечно ждать нового запроса, который физически уже не может прийти в данной сессии. Поэтому нужно на сервере делать тайм-аут по неактивности клиента. Со стороны клиента, кстати, тоже возможна ситуация, когда клиент послал запрос, и в этот момент линия отвалилась. Без таймаута он будет ждать ответа бесконечно.
То, что после сбоя или тайм-аута клиент заново открывает соединение совершенно нормально.
Записан
Страниц: [
1
]
Вверх
Печать
« предыдущая тема
следующая тема »
Перейти в:
Пожалуйста, выберите назначение:
-----------------------------
Qt
-----------------------------
=> Вопросы новичков
=> Уроки и статьи
=> Установка, сборка, отладка, тестирование
=> Общие вопросы
=> Пользовательский интерфейс (GUI)
=> Qt Quick
=> Model-View (MV)
=> Базы данных
=> Работа с сетью
=> Многопоточное программирование, процессы
=> Мультимедиа
=> 2D и 3D графика
=> OpenGL
=> Печать
=> Интернационализация, локализация
=> QSS
=> XML
=> Qt Script, QtWebKit
=> ActiveX
=> Qt Embedded
=> Дополнительные компоненты
=> Кладовая готовых решений
=> Вклад сообщества в Qt
=> Qt-инструментарий
-----------------------------
Программирование
-----------------------------
=> Общий
=> С/C++
=> Python
=> Алгоритмы
=> Базы данных
=> Разработка игр
-----------------------------
Компиляторы и платформы
-----------------------------
=> Linux
=> Windows
=> Mac OS X
=> Компиляторы
===> Visual C++
-----------------------------
Разное
-----------------------------
=> Новости
===> Новости Qt сообщества
===> Новости IT сферы
=> Говорилка
=> Юмор
=> Объявления
Загружается...