Спасибо, победилЦитата:
Вид для печати
Спасибо, победилЦитата:
Вот такая штука если в конфигурации задач стоит время выполнения моего сервера менее 40ms.
иногда пакеты склеиваются в один, чем меньше время , тем больше и чаще клей.
В чем может быть, ну или объясните может так и должно?
Это все происходит если я просто отсылаю счетчик клиенту в постоянном цикле, так просто тестирую.
-------------------------------------------
Если не сложно посмотрите код.
Вот в чем штука, все работает, пакеты не теряются, но бывает что если отвалиться соединения ( пропало питание на свиче )
Не всегда оно восстанавливается.
В чем может быть ошибка.
Спасибо.
CASE step OF
0:
hSocket:=SysSockCreate(SOCKET_AF_INET,SOCKET_STREA M,SOCKET_IPPROTO_TCP);
result_Ioctl:=SysSockIoctl(hSocket, SOCKET_FIONBIO, ADR(mode) );
step:=6;
6:
IF hSocket = SOCKET_INVALID THEN
step:=0;
ELSE
step:=1;
END_IF
1:
sa.sin_family:=SOCKET_AF_INET;
sa.sin_addr:=SOCKET_INADDR_ANY;
sa.sin_port:=SysSockHtons(80);
result_Bind:=SysSockBind(hSocket,ADR(sa), SIZEOF(sa));
result_Listen:=SysSockListen(hSocket, 1);
step:=2;
2:
hSockClient:=SysSockAccept(hSocket, ADR(sa), SIZEOF(sa));
step:=5;
5:
IF hSockClient <> 16#FFFFFFFF THEN
step:=3;
ELSE
step:=2;
END_IF
3:
Size_Recv:=SysSockRecv(hSockClient, ADR(Buff_Recv), 256, 0 );
IF Size_Recv > 0 THEN
Buff_Send := Buff_Send+1;
Size_Send:=SysSockSend(hSockClient, ADR(Buff_Send), 10 + 1, 0 );
step:=2;
ELSE
Buff_Send := Buff_Send+1;
Size_Send:=SysSockSend(hSockClient, ADR(Buff_Send), 10 + 1, 0 );
step:=2;
END_IF
4:
SysSockClose(hSockClient);
SysSockClose(hSocket);
step:=0;
END_CASE
1. SysSockListen должен возвратить 0. соответственно может потребовацо несколько вызовов.
2. SysSockAccept в ПЛК не имеет смысла (по крайней мере пока) можно не вызывать вовсе.
3. у тебя SysSockRecv и SysSockSend вызываюцо в одном цикле ПЛК - это методически неграмотно. нужно разнести по циклам.
4. не совсем понял что ты передаешь. Buff_Send - простое число? дворд там или ворд? почему diBufferSize равен 10 + 1? должно быть хотя бы SIZEOF( Buff_Send ).
5. зачем после чтения/передачи снова step:=2;?
6. если связь пропала то в течении какого то времени Size_Recv или Size_Send будут равны -1.
соответственно после этого чтобы связь востановить нужно закрыть сокет и и начать со step=0. при этом обратить внимание чтобы номер нового сокета был таким же.
7. SysSockIoctl - не обязательно
8. hSocket - понятно, что такое hSockClient? откуда он взялсо и почему прием/передача именно в этот сокет?
UDP: дошло hSockClient у тебя равно hSocket поэтому и связь есть. вощем hSockClient - лишнее. так как SysSockAccept вызывать не нужно.
1.SysSockListen должен возвратить 0. соответственно может потребовацо несколько вызовов.
Уменя всегдп = 0. Но раз уж говорите сделаю проверку, думаю не повредит.
2.SysSockAccept в ПЛК не имеет смысла (по крайней мере пока) можно не вызывать вовсе.
А как это, нет смысла? А если у меня на diSocket сидят несколько клиентов в очереди, как
Я их разбирать буду кто есть кто?
Я вот потому и использую SysSockAccept.
( далее просто будет два сервера один для обмена, другой web )
3. у тебя SysSockRecv и SysSockSend вызываюцо в одном цикле ПЛК - это методически неграмотно. нужно разнести по циклам.
Просто по разным шагам раскидать?
6. если связь пропала то в течении какого то времени Size_Recv или Size_Send будут равны -1.
соответственно после этого чтобы связь востановить нужно закрыть сокет и и начать со step=0. при этом обратить внимание чтобы номер нового сокета был таким же.
Угу, спасибо – что-то потерял обрыв, поправил.
А что значит обратить внимание чтоб номер нового сокета был таким же после шага 0: ?
diBufferSize равен 10 + 1? – это просто так написал там у меня будет len(Buff_Send) + 1. + 1 просто 0 в конце будет.
5. зачем после чтения/передачи снова step:=2;?
Ну я думаю так, что если клент отвалился, то его надо поднять на место. Ну и думаю тут разбор клиентов по hSockClient.
Хотя у меня клиент будет всего один.
step:=2; - переход суда решила один вопрос связанный с потерей пакетов, т.е после приема в плк, в моем данном примере
отправка происходит моментам если нет приема, прост отсылает клиенту пакет-счетчик. Так вот после того как плк принял
данные, он сразу начинает отправлять, и клиент теряет первые 3-5 пакетов, если перехожу на stap:=2 то все нормуль.
у тебя SysSockRecv и SysSockSend вызываюцо в одном цикле ПЛК - это методически неграмотно. нужно разнести по циклам.
Ну может потеря была и вот по этой причине не грамотности, попробую разнести.
Спасибо.
Не подскажете, у кого какие скорости при обмене по tpc получаются? (плк 150)
Пакетов в секунду (ну я считаю пакет – строка 255).
Просто у меня как-то маловато получается, совсем.
8 - пакетов в одну сторону за секунду.
Цикл выполнения 30ms, меньше почему-то не получается, если меньше то происходит или склеивание пакетов,
или частые разрывы в соединении?!
Если мне надо поднять два сервера, один допустим сервер обмена порт 44444, другой web порт 80.
Как правильно это делать?
Не могу понять, если вызываю в разных 2х POU - SysSockCreate(SOCKET_AF_INET,SOCKET_STREAM,SOCKET_ IPPROTO_TCP);
Не работает ни один.
Думал, так – но не знаю правильно ли это?
0:
hSocket:=SysSockCreate(SOCKET_AF_INET,SOCKET_STREA M,SOCKET_IPPROTO_TCP);
result_Ioctl:=SysSockIoctl(hSocket, SOCKET_FIONBIO, ADR(mode) );
step:=6;
6:
IF hSocket = SOCKET_INVALID THEN
step:=0;
ELSE
step:=1;
END_IF
1:
(* Web ---------------------- *)
sa_web.sin_family:=SOCKET_AF_INET;
sa_web.sin_addr:=SOCKET_INADDR_ANY;
sa_web.sin_port:=SysSockHtons(80);
result_Bind_Web:=SysSockBind(hSocket,ADR(sa_web), SIZEOF(sa_web));
(* Web ---------------------- *)
sa.sin_family:=SOCKET_AF_INET;
sa.sin_addr:=SOCKET_INADDR_ANY;
sa.sin_port:=SysSockHtons(44444);
result_Bind:=SysSockBind(hSocket,ADR(sa), SIZEOF(sa));
result_Listen:=SysSockListen(hSocket, 1);
step:=2;
2:
hSockClient:=SysSockAccept(hSocket, ADR(sa), SIZEOF(sa));
hSockClientWeb:=SysSockAccept(hSocket, ADR(sa_web), SIZEOF(sa_web));
step:=5;
5:
IF hSockClientWeb <> 16#FFFFFFFF THEN
step:=3;
ELSE
step:=2;
END_IF
IF hSockClient <> 16#FFFFFFFF THEN
step:=3;
ELSE
step:=2;
END_IF
ты невнимательно читаешь сообщения по форуму )
в ПЛК - один сокет (допустим сервер) = одно подключение = ОДИН клиент )
поэтому SysSockAccept - полная лажа. код работает только потому что SysSockAccept возвращает номер сокета созданного SysSockCreate.
если будет два клиента нужно создавать два сокета сервера )
Чтобы создать несколько сокетов нужно SysSockCreate вызывать в разных циклах. Иначе SysSockCreate возвращает номер первого созданного сокета.
"обратить внимание" значит посмотреть в кодесисе с каким номером сокет открылся. по опыту если открывается с другим (значит прошлый не закрылся) то связь не востанавливаецо. в таком случае нужно перепрошить ПЛК на самую свежую прошивку.
ты проверяешь результат SysSockCreate в следующем цикле. это тоже методически неграмотно проверяй в том же.
Скорость в цифрах не помню. но на обработку одного запроса уходит два-три цикла ПЛК (у меня циклы от 5ти до 20ти ms)
Создаю 2 POU, В менеджере задач, выставляем им время циклов (20ms и 30ms).Цитата:
Чтобы создать несколько сокетов нужно SysSockCreate вызывать в разных циклах. Иначе SysSockCreate возвращает номер первого созданного сокета.
"обратить внимание" значит посмотреть в кодесисе с каким номером сокет открылся. по опыту если открывается с другим (значит прошлый не закрылся) то связь не востанавливаецо. в таком случае нужно перепрошить ПЛК на самую свежую прошивку.
В каждом POU вызываю SysSockCreate, не один не работает?
Версия прошивки 2.15. Не пойму в чем дело.
Все остальное вроде вкурил.
SysSockAccept и неграмотность уберу – может 5ms выиграю.
Спасибо.
За POU не скажу, достаточно двух FB ) Сокеты открываюцо "системой". Вылоняецо первый POU затем второй. Это все один цикл ПЛК ) я канеш могу ошибацо ибо таких огородов (с несколькими POU) не горожу ) Напиши один работающий FB а дальше юзай его экземпляры )
Тут вот какая штука выходит, первый сервер у меня для обмена работает 30ms.Цитата:
Напиши один работающий FB а дальше юзай его экземпляры
Второй веб-сервер, работает 150ms иначе просто то что летит от браузера видимо не успевает
попасть в 30ms, при 150ms веб сервер работает. Если я запихну в два FB как мне сделать разные
скорости исполнения. Одн то я сделаю допустим 30ms, а вот вторую как?
Спасибо.
Спасибо, разобрался, невнимательно просто делал.