Я реализовал Modbus через TCP в качестве серверного программного обеспечения на Python.Приложение является многопоточным и сильно зависит от стандартных библиотек.У меня проблемы с управлением соединением на стороне сервера.Между тем моя реализация в качестве Modbus поверх TCP в качестве клиента работает просто отлично.
Описание реализации
- Сервер многопоточный, один поток управляет сокетом SOCK_STREAM для получения кадров
- select используется из соображений эффективности
- Семафор используется для предотвращения одновременного доступа к ресурсам сокета при отправке или получении
- Инкапсуляция верхнего уровня Modbus выполняется прозрачно с помощью методов отправки и получения, этоВ любом случае, только вопрос построения фрейма с правильным заголовком и полезной нагрузкой ...
- Запускаются другие потоки, внутри него вызываются методы отправки и получения Modbus.
Контекст TCP
TCP запущен и работает, привязан к порту, настроен на максимальное количество клиентов и прослушивается.
Трассировки в wireshark show:
- Клиент: SYN
- Мой сервер приложений: SYN, ACK
- Клиент: ACK
На стороне сервера был создан совершенно новый сокет какожидается и привязан к клиентскому сокету.
Пока все хорошо.
Контекст Modbus
- Клиент: Отправить кадр Modbus,Флаги TCP = 0x18, что означает ACK + PUSH
- Мой сервер приложений: Не ожидает и отправляет один пустой кадр TCP ACK .
- Клиент: Ожидание кадра Modbusс флагом tcp ack.Поэтому он принимает это за ошибку и просит закрыть соединение.
Следовательно, мое серверное программное обеспечение не может отправить какой-либо фактический ответ впоследствии, так как сокет на стороне клиента закрыт или уже закрыт.
Моя проблема
- Я получаю кадр Modbus, который должен обработать основной поток (на стороне сервера)
- Обработка занимает несколько мс, в то время как TCP ACKфрейм отправляется через сокет моего сервера, тогда как я бы не хотел ничего отправлять!
Есть ли у вас какие-либо идеи о том, как управлять поведением ACK?Я читал материал об алгоритме naggle, но, похоже, он не входит в сферу проблемы здесь ... Я не уверен, что какой-либо вариант метода setsockopt решит и мою проблему, но я могу ошибаться.
Если у вас есть предложения, я очень заинтересован ... Надеюсь, я достаточно ясен.