Работа с сокетами в Codesys V3.5 #1

Приступаем к работе с сокетами в среде разработки Codesys. Это первая статья, в которой будет создан сокет, установлено TCP соединение и произойдет передача данных. ПЛК выступает в роли клиента и весь код создан с использованием стандартных библиотек.

Сокеты

Здесь под сокетами понимается способ взаимодействия любого приложения с системой на которой оно работает. Сокет — это интерфейс, который по сути представляет собой совокупность адреса в сети и используемого порта. Еще мы тут можем добавить про файловые дискрипторы Unix, но это если вы захотите углубиться.

Как минимум все должны были сталкиваться с Modbus TCP вот там и была работа с сокетами.

Для определения сокета мы оперируем тремя переменными: Семейство сокетов, тип сокета и протокол.

Семейство сокетов определяет множество типов сокетов. В Codesys представлено большое количество семейств, но свое внимание стоит заострить на основных

  • SOCKET_AF_INET — Протоколы IPv4
  • SOCKET_AF_LOCAL — сокеты для локального межпроцессного взаимодействия
  • SOCKET_AF_ROUTE — сокет маршрутизации

Но есть шанс, что для решения большинства стандартных задач мы будем использовать SOCKET_AF_INET.

Вторая переменная — тип сокета.

  • SOCKET_STREAM — тип обеспечивает последовательный, надежный, ориентированный на установление двусторонней связи поток байтов.
  • SOCKET_DGRAM — поддерживает двусторонний поток данных. Не гарантируется, что этот поток будет последовательным, надежным, и что данные не будут дублироваться. Важной характеристикой данного сокета является то, что границы записи данных предопределены.
  • SOCKET_RAW — обеспечивает возможность пользовательского доступа к низлежащим коммуникационным протоколам, поддерживающим сокет-абстракции. Такие сокеты обычно являются датаграм- ориентированными.

Несмотря на такой набор мы будем использовать SOCKET_STREAM большую часть времени.

И последняя переменная, конкретизирующая наш протокол

  • SOCKET_IPPROTO_IP — IP уровень
  • SOCKET_IPPROTO_TCP — TCP
  • SOCKET_IPPROTO_UDP — UDP
  • SOCKET_IPPROTO_RAW — обычный IP пакет(для тех кто хочет сделать свой протокол)

Библиотека Codesys SysSocket

Все взаимодействие с сокетами осуществляется через библиотеку SysSocket

Место где ее можно найти

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

Имея в памяти хэндлер уже появится возможность принимать и отправлять данные.

Создание SysSocket.SysTypes.RTS_IEC_HANDLE

Чтобы не пугаться RTS_IEC_HANDLE это псевдоним для обычного указателя. Чтобы его создать необходимо воспользоваться функцией SysSockCreate

Описание входов и возвращаемых значений

На вход отдаются семейство для сокета, тип сокета и протокол, а также указатель на результат выполнения этой функции.

Возвращает функция хэндлер.

Установка соединения с сервером

Так как есть ручка, за которую мы будем дергать, то пора установить соединение с сервером.

Установка соединения с сервером происходит благодаря функции SysSockConnect

На вход отдаем хэндлер, указатель на переменную типа SOCKADDRESS и размер этой структуры.

SOCKADDRESS — это структура, которая содержит всю необходимую информацию для установки соединения

Структура имеет следующий вид:

Описание структуры SOCKADDRESS
  • sin_family — хранит информацию о семействе сокетов
  • sin_port — идентификационный номер порта, который был сконвертирован при помощи функции SysSockHtons в порядок байтов хоста
  • sin_addr — объединение INADDR
  • И массив, который нас не интересует.

INADDR — объединение, которое хранит IP адрес в различных формах.

Отправка данных SysSockSend

Функция SysSockSend используется для отправки данных по TCPv4 сокету

Сигнатура функции SysSockSend

Возвращает функция количество переданных байтов и если количество равно 0, то это ошибка.

На вход принимает:

  • hSocket — наше соединение
  • pbyBuffer — указатель на буффер с данными для отправки
  • diBufferSize — максимальная размерность буффера
  • diFlags — Параметр flags может быть использован для влияния на поведение функции за пределами опций, указанных для связанного сокета.
  • pResult — указатель на переменную, которая будет содержать результат работы функции.

Прием данных SysSockRecv

Тут как в предыдущей функции только на прием.

Сигнатуры функции SysSockRecv

Возвращает количество принятых байт

  • hSocket — наше соединение
  • pbyBuffer — указатель на буффер с данными для отправки
  • diBufferSize — максимальная размерность буффера
  • diFlags — Параметр flags может быть использован для влияния на поведение функции за пределами опций, указанных для связанного сокета.
  • pResult — указатель на переменную, которая будет содержать результат работы функции.

Разработка функционального блока для работы с сокетами

Теперь я вам покажу как может работать вся эта теория.

Создам функциональны блок со следующими методами

Сигнатура функционального блока
  • Connect — соединение с сервером
  • CreateSocket — создание сокета
  • FB_Init
  • Rcv — прием данных
  • Send — отправка данных

Внутри функционального блока я объявил следующие переменные

Внутри тела функционального блока кода нет.

В первую очередь надо подготовить структуру SOCKADDRESS. Этот процесс происходит в методе FB_Init()

Метод CreateSocket имеет следующую реализацию

Возвращает INT, где значение 200 -OK, 500 — Error

Метод Send принимает на вход ссылку на буффер и размерность этого буффера

Реализация метода Send

Ну и реализация метода Rcv

Дальше в основном теле программы через CASE реализуем нужное нам поведение плюс объявим все то, что на мне хватало

Что в итоге должно получиться. Мы должны отправить данные на сервер, а получить от сервера следующие данные

Эти данные должны прийти к нам в Buffer, а после, благодаря тому, что будут скопированы в объединение

Будут преобразованы в структуру

Если интересно что это за надпись на первой строчке то это прагма выражение аттрибутов, которая говорит компилятору, что в данной структуре не используются отступы и все данные идут сразу друг за другом.

Вот что у нас пришло на сервер

Отправляли мы следующие данные:

А вот что пришло в ответ

На этом будем считать, что с сокетами мы познакомились.

Обратная связь

Телеграм канал с новостями и заметками здесь.

Телеграм-бот для ваших предложений и вопросов здесь

Группа в VK здесь

Почта для связи: info@engcore.ru

Ответить