Приступаем к работе с сокетами в среде разработки Codesys. Это первая статья, в которой будет создан сокет, установлено TCP соединение и произойдет передача данных. ПЛК выступает в роли клиента и весь код создан с использованием стандартных библиотек.
- Сокеты
- Библиотека Codesys SysSocket
- Разработка функционального блока для работы с сокетами
- Обратная связь
Сокеты
Здесь под сокетами понимается способ взаимодействия любого приложения с системой на которой оно работает. Сокет — это интерфейс, который по сути представляет собой совокупность адреса в сети и используемого порта. Еще мы тут можем добавить про файловые дискрипторы 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 — это структура, которая содержит всю необходимую информацию для установки соединения
Структура имеет следующий вид:

- sin_family — хранит информацию о семействе сокетов
- sin_port — идентификационный номер порта, который был сконвертирован при помощи функции SysSockHtons в порядок байтов хоста
- sin_addr — объединение INADDR
- И массив, который нас не интересует.
INADDR — объединение, которое хранит IP адрес в различных формах.
Отправка данных SysSockSend
Функция SysSockSend используется для отправки данных по TCPv4 сокету

Возвращает функция количество переданных байтов и если количество равно 0, то это ошибка.
На вход принимает:
- hSocket — наше соединение
- pbyBuffer — указатель на буффер с данными для отправки
- diBufferSize — максимальная размерность буффера
- diFlags — Параметр flags может быть использован для влияния на поведение функции за пределами опций, указанных для связанного сокета.
- pResult — указатель на переменную, которая будет содержать результат работы функции.
Прием данных SysSockRecv
Тут как в предыдущей функции только на прием.

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

- Connect — соединение с сервером
- CreateSocket — создание сокета
- FB_Init
- Rcv — прием данных
- Send — отправка данных
Внутри функционального блока я объявил следующие переменные

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


Возвращает INT, где значение 200 -OK, 500 — Error
Метод Send принимает на вход ссылку на буффер и размерность этого буффера

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


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


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

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

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

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

На этом будем считать, что с сокетами мы познакомились.
Обратная связь
Телеграм канал с новостями и заметками здесь.
Телеграм-бот для ваших предложений и вопросов здесь
Группа в VK здесь
Почта для связи: info@engcore.ru
