Следите за указателем на результат, как только появится ошибка, смело закрывайте соединение и открывайте по новой, время сократится. Конечно всё в разумных пределах,ведь заоанее не известно сколько будет кабель отключен
Следите за указателем на результат, как только появится ошибка, смело закрывайте соединение и открывайте по новой, время сократится. Конечно всё в разумных пределах,ведь заоанее не известно сколько будет кабель отключен
какой функции?
В онлайне посмотрел результаты все - 0, да и как то отреагировать программа не успевает, ПЛК вешается.
Что-то чувствую идея сервера на базе ПЛК304 забуксовала!
Да быть такого не может, насколько помню при разрыве кабеля, что то типа 519 ошибки должно было пробится, вот в этом кодеCASE state OF
TS_INIT:
diSocket:=SysSockCreate(SOCKET_AF_INET,SOCKET_STRE AM,SOCKET_IPPROTO_IP,pResult);
IF diSocket>0 AND diSocket<>16#FFFFFFFF THEN
inad.ulAddr := SOCKET_INADDR_ANY;
sa.sin_family := SOCKET_AF_INET;
sa.sin_port := SysSockHtons(PORT);
sa.sin_addr := inad;
IF (SysSockBind(diSocket,ADR(sa),SIZEOF(sa)))<0 THEN
state:=TS_CLOSE;
ELSIF (SysSockListen(diSocket,1))<0 THEN
state:=TS_CLOSE;
ELSE
SysSockIoctl(diSocket,SOCKET_FIONBIO,ADR(dnt));
state:=TS_OPEN;
END_IF
ELSE
;// state := TS_CLOSE;
END_IF
TS_OPEN:
sa_size:=SIZEOF(sa);
clSocket:= SysSockAccept(diSocket, ADR(sa), ADR(sa_size),pResult);
IF (*clSocket>0 AND*) clSocket<>16#FFFFFFFF THEN // ждет подключений клиентов и только тогда переходит в режим TS_WAIT
SysSockIoctl(clSocket,SOCKET_FIONBIO,ADR(dnt));
state:=TS_WAIT;
tx:=TIME_TO_DWORD(TIME());
END_IF
TS_CLOSE:
state:=TS_PAUSE;
tx:=TIME_TO_DWORD(TIME());
TS_WAIT:
rcvCount:=SysSockRecv(clSocket,ADR(RXTXBuf[0]),256,0,pResult);
IF rcvCount>0 THEN
disp(staff:=ADR(RXTXBuf));
SysMemSet(ADR(RXTXBuf[8]),0,248);
IF disp.unitID <> 1 THEN
funoff(unit:=disp.unitID);
SysMemCpy(ADR(RXTXBuf[4]),ADR(funoff.staff[0]),funtre.size+2);
pos:=WORD_TO_INT(funoff.size+6);
ELSE
CASE disp.kfunc OF
1:
fununo(data:=ADR(disp.data),unit:=disp.unitID);
SysMemCpy(ADR(RXTXBuf[4]),ADR(fununo.staff[0]),fununo.size+2);
pos:=WORD_TO_INT(fununo.size+6);
3:
funtre(data:=ADR(disp.data),unit:=disp.unitID);
SysMemCpy(ADR(RXTXBuf[4]),ADR(funtre.staff[0]),funtre.size+2);
pos:=WORD_TO_INT(funtre.size+6);
15:
fundecvis(data:=ADR(disp.data),unit:=disp.unitID);
SysMemCpy(ADR(RXTXBuf[4]),ADR(fundecvis.staff[0]),fundecvis.size+2);
pos:=WORD_TO_INT(fundecvis.size+6);
16:
fundecsei(data:=ADR(disp.data),unit:=disp.unitID);
SysMemCpy(ADR(RXTXBuf[4]),ADR(fundecsei.staff[0]),fundecsei.size+2);
pos:=WORD_TO_INT(fundecsei.size+6);
ELSE ;
END_CASE
END_IF
SysSockSend(clSocket,ADR(RXTXBuf[0]),pos,0,pResult);
tx:=TIME_TO_DWORD(TIME());
END_IF
IF (TIME_TO_DWORD(TIME())-tx)>timeouter THEN
IF clSocket>=0 THEN
state:=TS_OPEN;
END_IF
END_IF
TS_PAUSE:
IF (TIME_TO_DWORD(TIME())-tx)>5000 THEN
state:=TS_INIT;
END_IF
STOP:
IF clSocket>0 AND clSocket<>16#FFFFFFFF THEN
SysSockClose(clSocket);
clSocket:=16#00000000;
END_IF
IF diSocket>0 AND diSocket<>16#FFFFFFFF THEN
SysSockClose(diSocket);
diSocket:=16#00000000;
END_IF
ELSE
;
END_CASE;
Спасибо!
Попробую поковырять Ваш пример, что выйдет отпишусь!
Последний раз редактировалось Леонид; 19.08.2014 в 18:46.
А этот код был Вами реализован на ПЛК304?
Он работал?
Какая версия CoDeSys и библиотеки SysSocket использовалась?
И еще выложите пожалуйста, если не сложно, текст объявления переменных и структур.
Спасибо!
Последний раз редактировалось Леонид; 19.08.2014 в 21:40.
На устройстве "CODESYS_Control_Win_V3" код работает, вытаскиваю провод из клиента и все нормально, программа продолжает работать, если тот же код сервера запустить или на ПЛК304 или на ПЛК308 и вытащить провод из клиента, то ПЛК зависают, втыкаю провод обратно ПЛК начинает снова работать только еще почему-то сильно увеличивается время скана.
Что делать?
Как то упустил тему из вида, так понимаю код сервера реализован и что там с указателями,как в моем коде pResult, я совой код конечно испытывал на 304 но этот пример как раз без контроля ошибок, а так их перечень в бибке cmperors, хотя в принципе это не важно, хотя бы в любом месте вернулось значение больше нуля, стоит переподключить соединение
Он работал?
Какая версия CoDeSys и библиотеки SysSocket использовалась?
И еще выложите пожалуйста, если не сложно, текст объявления переменных и структур.
Спасибо!
Я все таки конкретно ваш код не пробовал, но я не вижу в нем принципиальных отличий.
Проблема в том , как я уже писал, что видимо ПЛК не успевает отреагировать на какие либо ошибки, так как мгновенно "подвисает", и выполнение прогрыммы останавливается, но стоит воткнуть провод обратно в ПЛК клиент как через некоторое время, программа сервера оживает!
Мне кажется что так должны работать сокеты в блокирующем режиме, но я ведь перевожу в НЕ блокирующий!
Последний раз редактировалось Леонид; 24.08.2014 в 16:50.
да работало на 304,это было давно, я бы уже по другому собрал сервак. И не будем забывать, что в 12 году с этим контроллером я работал в v3.4Код:FUNCTION_BLOCK STATESOCKET VAR inad: INADDR; diSocket : RTS_IEC_HANDLE; clSocket : RTS_IEC_HANDLE; state : BYTE := 1; sa : SOCKADDRESS; sa_size : DWORD; RXTXBuf : ARRAY[0..255] OF BYTE; dnt: DINT := 1; tx: DWORD; rcvCount: DINT; pResult: POINTER TO RTS_IEC_RESULT; timeouter: DWORD := 10000; pos: INT; disp: SLAVE_DISPATCHER; funoff: SLAVE_NOT_UNITID; fununo: SLAVE_RD_COILS; funtre: SLAVE_RD_MULT_RG; fundecvis: SLAVE_WR_COILS; fundecsei: SLAVE_WR_MULT_RG; hold_reg: ARRAY[0..255] OF BYTE; END_VAR VAR CONSTANT STOP : BYTE := 0; TS_INIT: BYTE := 1; TS_OPEN: BYTE := 2; TS_CLOSE: BYTE := 3; TS_WAIT: BYTE := 4; TS_PAUSE: BYTE := 5; PORT: WORD := 502; END_VAR
А, нет, вру, вот реализация этого кода http://www.owen.ru/forum/showthread....l=1#post101265
Последний раз редактировалось capzap; 24.08.2014 в 16:57.