СТА 3/2018
Блокирующий режим По умолчанию некоторые функции библиотеки SysSocket являются блокирующими . Это значит, что вызов функции не возвращает управление программному коду до тех пор, пока он не выполнится. Блокирующими функциями являются Sys- SockAccept() , SysSockSend() , SysSockRecv() , SysSockSendTo() , SysSockRecvFrom() и так далее. Например, сервер включает прослушивание входящих со- единений с помощьюнеблокирующейфункции SysSockListen() , сразу после которой идёт вызов SysSockAccept() . Идо тех пор по- ка в очереди установленных соединений не появится хотя бы одно подключение, программа не будет исполняться дальше. Такой режим работы также называется синхронным. Естественно, такое поведение программы не является без- опасным, и при циклическом вызове программы в ПЛК мо- жет сработать сторожевой таймер или произойти выход в без- опасный режим – контроллер будет считать, что программа зависла. В ЗАПИСНУЮ КНИЖК У ИНЖЕ Н Е РА СТА 3/2018 87 www.cta.ru Листинг 14. Создание серверного UDP-сокета hServerSocket := SysSockCreate(SOCKET_AF_INET, SOCKET_DGRAM, SOCKET_IPPROTO_UDP, ADR(result)); // hServerSocket – системный идентификатор сокета сервера; // SOCKET_AF_INET – семейство, соответствующее сетевому протоколу IPv4; // SOCKET_DGRAM – тип создаваемого сокета (датаграммный сокет для UDP); // SOCKET_IPPROTO_UDP – протокол сокета UDP; // ADR(result) – указатель на идентификатор результата (RTS_IEC_RESULT). Листинг 15. Связывание серверного UDP-сокета с адресом result := SysSockBind(hServerSocket, ADR(serverAddress), SIZEOF(serverAddress)); // Дескриптор серверного сокета hServerSocket связывается с адресом сокета; // serverAddress, заданным структурой SOCKADDRESS. Листинг 16. Получение данных от UDP-клиента bytesRead := SysSockRecvFrom(hServerSocket, ADR(recvBuffer), SIZEOF(recvBuffer), 0, ADR(clientAddress), SIZEOF(clientAddress),ADR(result)); // hServerSocket - системный идентификатор сокета сервера; // bytesRead – количество полученных байт, в случае ошибки возвращается 0; // hServerSocket – системный идентификатор клиентского сокета; // ADR(recvBuffer) – указатель на переменную, в которую запишется получаемое сообщение; // SIZEOF(recvBuffer) – размер принимаемого сообщения; // Вместо 0 могут быть установлены опции приёма сообщений; // ADR(clientAddress) – указатель на структуру SOCKADDRESS, в которую запишется адрес клиента; // ADR(result) – указатель на идентификатор результата. Листинг 17. Отправка данных UDP-клиенту bytesSend := SysSockSendTo(hServerSocket, ADR(sendBuffer), SIZEOF(sendBuffer), 0, ADR(clientAddress), SIZEOF(clientAddress),ADR(result)); // ADR(sendBuffer) и SIZEOF(sendBuffer) – указатель на отправляемое сообщение // и размер отправляемого сообщения; // ADR(clientAddress) – указатель на структуру, в которой записан адрес сокета клиента. Листинг 18. Создание клиентского UDP-сокета hClientSocket := SysSockCreate(SOCKET_AF_INET, SOCKET_DGRAM, SOCKET_IPPROTO_UDP, ADR(result)); // hClientSocket – системный идентификатор клиентского сокета; // SOCKET_AF_INET – семейство, соответствующее сетевому протоколу IPv4; // SOCKET_DGRAM – тип создаваемого сокета (датаграммный сокет для UDP); // SOCKET_IPPROTO_UDP – протокол сокета (UDP); // ADR(result) – указатель на идентификатор результата (RTS_IEC_RESULT). Листинг 19. Обмен данными между UDP-клиентом и UDP-сервером bytesSend := SysSockSendTo(hClientSocket, ADR(sendMessage), SIZEOF(sendMessage), 0, ADR(clientAddress), SIZEOF(clientAddress), ADR(result)); bytesRecv := SysSockRecvFrom(hClientSocket, ADR(recvMessage), 256, 0, ADR(clientAddress), SIZEOF(clientAddress), ADR(result)); // hClientSocket – системный идентификатор сокета сервера; // bytesRead, bytesRecv – количество полученных и отправленных байт, // в случае ошибки возвращается 0; // ADR(clientAddress) – указатель на структуру SOCKADDRESS, в которую запишется адрес клиента; // ADR(result) – указатель на идентификатор результата.
RkJQdWJsaXNoZXIy MTQ4NjUy