PDA

Просмотр полной версии : Подвисание ПЛК110 М02 SysSockConnect



приборист
21.06.2017, 22:48
Добрый день!
Проблема такая:
ПЛК110-30 М02
0.3.68
ПЛК отправляет данные на внешний сервер.
Если ПЛК подключен к роутеру, а на роутере отсутсвует интернет, получаем подвисание на команде
SysSockConnect
При этом отключаются все выхода и приостанавливается программа.

При отсутствии подключения Ethernet (отключаем кабель из роутера) - все проходит нормально и SysSockConnect возвращает 0.

Код отправки на сервер (На старом ПЛК все работает без проблем)

CASE step OF 0:
nbRecv:=0;
nbSend:=0;
hSocket:=SysSockCreate(SOCKET_AF_INET, SOCKET_STREAM, 0);
IF hSocket <> SOCKET_INVALID THEN
sa.sin_family:=SOCKET_AF_INET;
dwIP:=SHL( SHL( SHL(
BYTE_TO_DWORD(arrIp[0] ), 8 )
OR BYTE_TO_DWORD( arrIp[1] ), 8 )
OR BYTE_TO_DWORD( arrIp[2] ), 8 )
OR BYTE_TO_DWORD( arrIp[3] );
sa.sin_addr:=SysSockHtonl(dwIP);
sa.sin_port:=SysSockHtons(port);
step:=1;
tries:=0;
ELSE
step:=4;
END_IF


1:
tries:=tries+1;
result:=BOOL_TO_DINT(SysSockConnect(hSocket, ADR(sa), SIZEOF(sa)));
IF result<0 THEN
step:=4;
tries:=0;
ELSE
step:=2;
END_IF


IF tries >20 THEN
triesGL:=triesGL+1;
step:=4;
END_IF


2:
tries:=tries+1;
nbSend:= SysSockSend (hSocket, ADR(arrPostData), sizeRead+LEN(strPost) ,0);
IF nbSend>0 THEN
step:=3;
tries:=0;
ELSE
step:=4;
END_IF
IF tries >10 THEN
triesGL:=triesGL+1;
step:=4;
END_IF


3:
tries:=tries+1;
nbRecv:= SysSockRecv (hSocket, ADR(strRecv), 1024, 0);
IF nbRecv>0 THEN
(*Проверка ответа*)
ELSIF nbRecv=-1 THEN
step:=4;
END_IF


IF tries >10 THEN
triesGL:=triesGL+1;
step:=4;
END_IF


4:
tries:=0;
SysSockClose (hSocket);
step:=0;
bGoGet:=FALSE;
END_CASE

_Pavel_
22.06.2017, 08:48
Добавьте в step 0 после создания сокета перевод в неблокирующий режим:
SysSockSetOption(hSocket, SOCKET_SOL, SOCK_NBIO, 0, 0);
где SOCK_NBIO: WORD:=16#1014;

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

lazy
22.06.2017, 09:19
я SysSockConnect и SysSockListen вызываю не в каждом цикле ибо да, они изрядно подтормаживают ПЛК.
например так то так:

m_y := m_y + 1;
IF ( m_y MOD 50 ) = 0 THEN
(* каждый пиЙсятый цикл *)
END_IF

приборист
22.06.2017, 10:04
Спасибо за советы, действительно помогло.
Правда следом притянуло новые проблему.
SysSockSend не отправляет больше 1460 байт (в блокирующем режиме я отправлял и 11000 байт разом, сейчас уменьшил пакет, данные отправляются).
SysSockRecv периодически возвращает -1 (Почитал соседние темы, добавил таймаут, буду пробовать с ним).

Будем наблюдать.