socat – многократные попытки соединения не проходят через последовательный порт

Вопрос или проблема

Я использую socat для маршрутизации последовательного ввода через сеть, чтобы управлять устройством Arduino через виртуальный COM-порт.

Моя команда для запуска socat выглядит так:

socat /dev/serial0,b500000,raw,echo=0 TCP-LISTEN:9876,nodelay,fork&

Это работает в первый раз, когда устройство подключается к порту :9876, все проходит отлично. Однако, если соединение сбрасывается с другой стороны (которая использует com2tcp на Windows), любые дальнейшие подключения будут передавать данные по сети на RasPi, хостящую socat, и выводить их на последовательное устройство, но данные не будут принимать из /dev/serial0. Мне нужно убить оригинальный процесс socat, подождать, пока порт освободится, и затем снова запустить socat. Поскольку RasPi работает без экрана, это неприятность, которую я бы предпочел избежать.

Есть ли способ разрешить несколько несинхронных соединений работать таким образом? Я предполагаю, что есть какая-то настройка, которую нужно ввести после echo=0, но я не могу понять, какая именно.

(Дополнительные заметки: скорость 500000 бод необходима, так как это скорость, требуемая для программного обеспечения, которое я использую, называемого GIMX. Цель этой настройки — подключиться к игровой консоли с устройствами в другой комнате, используя функционал удаленной игры для игры. Я установил эту команду в /etc/rc.local, чтобы запускать socat при загрузке, так как RasPi также используется как медиаплеер с Volumio; это просто работает в фоновом режиме.)


ИЗМЕНЕНИЕ: Я в конечном итоге отказался от маршрута socat/com2tcp и внедрил соединение, соответствующее RFC2247. Это означало, что мне не нужно было беспокоиться о ручной настройке скорости передачи, и, похоже, оно работает более стабильно. Я основывал это на информации из https://robosavvy.com/forum/viewtopic.php?t=7578, которая в основном дает полное представление о том, как это настроить. Хотя несколько ссылок мертвы, в ней есть необходимая информация для установления соединения.

Я полагаю, что команда, которую я искал, была “end-close”, однако я не тестировал это перед тем, как перейти на новую настройку.

На локальной сети вы, вероятно, захотите использовать UDP вместо TCP. Вы получите лучшую задержку, и проблема с соединением, вероятно, исчезнет. Быстрый поиск приводит к программе под названием COM2UDP.

Ответ или решение

Тема: Решение проблемы с многократными попытками подключения через socat в проектах с Arduino

Ваша проблема с использованием socat для маршрутизации последовательного ввода через сеть на Raspberry Pi, связанная с управлением устройством Arduino, является распространенной среди разработчиков, работающих с удаленными последовательными устройствами. Рассмотрим ваше текущее решение и возможные пути оптимизации.

Описание проблемы

Вы используете следующую команду для запуска socat:

socat /dev/serial0,b500000,raw,echo=0 TCP-LISTEN:9876,nodelay,fork&

Эта команда корректно работает при первом подключении к порту 9876, однако, если соединение обрывается, вы сталкиваетесь с тем, что дальнейшие подключения не обеспечивают двустороннюю связь: данные передаются из сети на Raspberry Pi и далее на последовательный порт, но данные не принимаются с /dev/serial0. Вы должны завершать процесс socat, чтобы освободить порт, что создает неудобства в работе с headless Raspberry Pi.

Предложенное решение

Для решения вашей проблемы существует несколько подходов, которые могут включать изменения в настройках socat:

  1. Разрешение повторного использования сокетов:
    Вы можете добавить опцию SO_REUSEADDR к вашей команде socat. Эта опция позволит повторно использовать адреса и порты, что может помочь вам избежать необходимости перезапуска socat после разрыва соединений. Соответствующая команда будет выглядеть так:

    socat /dev/serial0,b500000,raw,echo=0 TCP-LISTEN:9876,nodelay,fork,bind=0.0.0.0,reuseaddr&
  2. Использование опции end-close:
    Как вы сами упомянули, опция end-close может помочь вам в управлении завершением соединений. Эта опция закрывает все открытые соединения, связанные с сокетом, когда одно из них закрывается. Добавьте ее в вашу команду:

    socat /dev/serial0,b500000,raw,echo=0 TCP-LISTEN:9876,nodelay,fork,end-close&
  3. Переход на более надежный протокол:
    Если вы уже пробовали использовать более сложные настройки, рассмотрите возможность использования COM2UDP, как упомянуто в вашем обсуждении. Протокол UDP может обеспечить более низкую задержку и отсутствие проблем с поддержанием соединения. Это может оказаться более эффективным для приложения, работающего в локальной сети.

  4. Упрощение настройки и дополнительные библиотеки:
    Для долгосрочного решения вы также можете рассмотреть использование специализированных библиотек, таких как rfc2217, которые обеспечивают надежное управление портами, не требуя от вас глубокого понимания сетевых деталей.

Заключение

Ваш текущий подход к использованию socat является хорошим, однако в нем есть возможности для улучшения, которые могут усилить его эффективность и устранить проблемы с управлением подключениями. Попробуйте включить предложенные изменения и протестируйте их в вашей среде. Это должно позволить вам избежать необходимости вручную перезапускать socat и улучшить взаимодействие с вашими устройствами.

Надеюсь, эти рекомендации окажутся полезными для дальнейшего упрощения вашего проекта с Arduino и Raspberry Pi.

Оцените материал
Добавить комментарий

Капча загружается...