PDA

Просмотр полной версии : PING удаленного компьютера через Ethernet средствами ПЛК



asup_svk
16.06.2009, 09:03
чем можно организовать сие мероприятие? :confused:
SysLibSockets?
п.с. просто необходимо чтобы при обрыве Ethernet параметр привязанный к пингу переходил в ноль тем самым меняя режим работы ПЛК-100, зашитый в программу

Филоненко Владислав
16.06.2009, 09:11
да, именно им.
тип - Sock_dgram == 2
протокол -ipproto_icmp == 1

asup_svk
16.06.2009, 12:54
спасибо!
то есть это будет выглядеть так

socket:=SysSockCreate(SOCKET_AF_INET, SOCKET_DGRAM, SOCKET_IPPROTO_ICMP);
а IPадрес и номер порта удаленной машины где нужно указывать?
а величины размера (len) и адреса (buf) буфера откуда брать? :confused:

Малышев Олег
17.06.2009, 15:33
Пример пинга

asup_svk
18.06.2009, 07:42
Олег
спасибо.
но вопросы те же...
в sock_addr.sin_addr и sock_addr.sin_port я должен записать IP адрес и порт машины вместо 16#0A00065F и 16#0800?
так ли это?

Малышев Олег
18.06.2009, 14:25
Именно так, IP=10.0.6.95

asup_svk
23.06.2009, 07:47
спасибо Олег.. проработал пример под себя....все работает супер!

Alber
17.07.2014, 20:04
Супер гууууд
А можно чуть подробней: как писать IP (16#0A00065F - в таком или 10.0.6.95 в таком виде!)
и что имеется ввиду под номером порта! 16#0800
обычно пингуем без всяких портов (я имею ввиду комп виндовс, просто ип и все)
Здесь просто если со вторым ПЛК, то тогда понятно, что за порт, а вот если комп виндос то что за порт? и где его посмотреть?

Alber
17.07.2014, 20:10
16#0A00065F это в каком формате и как 10.0.6.95 перевести в этот формат

petera
17.07.2014, 20:17
... а вот если комп виндос то что за порт? и где его посмотреть?

Порт 137 (NETBIOS-NS (NetBIOS Name Service))

Alber
17.07.2014, 21:00
Если точнее, то я хочу ПЛК 100 пинговать компьютер с виндой
что надо ип вбить понятно а в какой форме и как недопонимаю и что с портом делать (какой вбивать)

Alber
17.07.2014, 21:05
web_stat:=1;
sock_adr.sin_addr:=16#0A00065F;
(*IP Адрес опрашиваемого устройства {создается сокет на опрашивающем устройстве}*)
sock_adr.sin_family:=SOCKET_AF_INET;
(*Стек протоколов TCP/IP*)
sock_adr.sin_port:=16#0800;
(*Старший байт- Тип ICMP пакета {08 - Ping} младший байт- код ICMP пакета { 0- Ping}*)
sock_adr1.sin_addr:=16#0A000626;
(*То же самое для функции чтения {в принципе не важно}*)
sock_adr1.sin_family:=SOCKET_AF_INET;
sock_adr1.sin_port:=16#1111;
my_BUFs:='qwertyuiopasdfghjklzxcvbnm123456';
----------------------------------------------------------------------------------
это из примера, а что править!:
вот это sock_adr.sin_addr:=16#0A00065F; тогда как переводить
и вот это sock_adr.sin_port:=16#0800; а здесь 137 как перевести
а это тоже на что то править или не надо sock_adr1.sin_addr:=16#0A000626;
sock_adr1.sin_port:=16#1111;

Alber
17.07.2014, 21:10
кажется ясно: надо 16# отбрасывать и без точек в HEXe
но вот в порту стоит впереди 0 тогда 137 будет 0089 или 89 просто!

Alber
17.07.2014, 21:12
sock_adr1.sin_addr:=16#0A000626;
sock_adr1.sin_port:=16#1111;
с этим не совсем ясно

Alber
17.07.2014, 21:49
все изменил, но ни одного положительного запроса!
(*Время ожидания истекло считываем данные*)
IF FIND(my_BUFr,'pasd')<>0 THEN
suces:=suces+1;
(*Сравниваем переданные и принятые данные в случае идентичности увеличиваем счетчик удачного Ping*)
ELSE
faul:=faul+1;
(*В противном случае увеличиваем счетчик неудачного Ping запроса*)

растет бесконечно faul:=faul+1; а suces:=suces+1; все время равно 0 куда копать!?
Правда есть еще такой параметр как sock_adr.sin_family:=SOCKET_AF_INET; - что он дает? равен 2, может его поменять, а на что тогда?

sgmj
08.04.2015, 18:12
Не буду плодить темы напишу здесь. Задача та же - пинговать ПК с ОВЕНа (ПЛК110).

Как основу брал этот же пример.

Есть несколько вопросов и проблем:
1) Я правильно понимаю, что ICMP использует датаграммы (тип коммуникации SOCKET_DGRAM) и общая схема работы клиента на датаграммах такова:
1.1. создаем TCB структуру SOCKADDRESS для сервера (машины, которую будем пинговать) с нужными настройками (serv.sin_addr:= SERV_IP, serv.sin_family:=SOCKET_AF_INEТ, serv.sin_port := ICMP_TYPE_CODE)
1.2. создаем TCB структура SOCKADDRESS для клиента (ПЛК) с такими же настройками, за исключением адреса (client.sin_addr:= PLC_IP, client.sin_family:=SOCKET_AF_INEТ, client.sin_port := ICMP_TYPE_CODE)
1.3. заполняем буфер проверочными данными для отправки (например, 32 байта символов sBuf :STRING := 'abcdefghijklmnopqrstuvwabcdefghi')
1.4. делаем вызов сокета, получаем дескриптор ( sock := SysSockCreate(SOCKET_AF_INET, SOCKET_DGRAM, SOCKET_IPPROTO_ICMP) )
1.5. связываем сокет с адресом клиента ( bindClient := SysSockBind(sock, ADR(client), SIZEOF(client)) )
1.6. пишем буфер в сокет ( bufSend := SysSockSendTo(sock, ADR(sBuffer), 32, 0, ADR(serv), SIZEOF(serv)) )
1.7. дальше пишем в буфер приема rBuf ( recv:=SysSockRecvFrom(sock,ADR(rBuf),32,0,ADR(clie nt),SIZEOF(client)) ), выждав какой то таймаут
1.8. сравниваем содержимое переданного с принятым
?
2) Одиночный пакет с ПЛК уходит нормально, доходит до ПК, WireShark его видит. На первый взгляд с пакетом все ОК - тип 08 (эхо-запрос) , код 00. Но почему то я вижу коды 61("а") и 62 ("b") в качестве идентификатора ICMP пакета и коды 63 64 ("с" "d") в качестве порядкового номера. Это почему так? Я думал, что вся эта возня с структурами SOCKADRESS как раз и должна отделить всякие заголовки от данных из буфера.
17606
3) Самая большая проблема сейчас - как видно с того же скрина WireShark`а ПК не хочет слать в ответ ICMP пакет. В чем дело???
4) как работает SysSockRecvFrom? Он может сколько угодно ждать ответа, проверяя буфера сокета на предмет пришедших данных при каждом цикле работы ПЛК?

Филоненко Владислав
09.04.2015, 07:55
Пример пинга во вложении.

sgmj
09.04.2015, 10:55
Пример пинга во вложении.

Не работает (см. скриншоты). Пакеты на ПК приходят, но ПК на них не отвечает.
адрес ПЛК110-24: 10.8.11.230 (16#0A080BE6)
адрес пингуемого ПК с Windows 7: 10.8.11.104 ( 16#0A080B68)
1762017621

Yegor
09.04.2015, 12:28
Вот мой рабочий пинг. ПЛК160 — 10.0.6.10, ПК — 10.0.6.9.

17628


3) Самая большая проблема сейчас - как видно с того же скрина WireShark`а ПК не хочет слать в ответ ICMP пакет. В чем дело???Фаервол?
4) как работает SysSockRecvFrom? Он может сколько угодно ждать ответа, проверяя буфера сокета на предмет пришедших данных при каждом цикле работы ПЛК?Как и многие другие «поточные» функции, она тут же возвращает число прочитанных байт, даже если это число равняется нулю. Очень удобно на самом деле (см. мой пример). Если, скажем, в примере от Владислава зачем-то делается задержка после отправки запроса, то я легко обхожусь без неё как раз за счёт моментального возврата SysSockRecvFrom.

sgmj
09.04.2015, 12:59
Вот мой рабочий пинг. ПЛК160 — 10.0.6.10, ПК — 10.0.6.9.

17628

Фаервол?Как и многие другие «поточные» функции, она тут же возвращает число прочитанных байт, даже если это число равняется нулю. Очень удобно на самом деле (см. мой пример). Если, скажем, в примере от Владислава зачем-то делается задержка после отправки запроса, то я легко обхожусь без неё как раз за счёт моментального возврата SysSockRecvFrom.
Спасибо большое за пример - хорошо структурирован. Что значит "поточные"? SysSockRecvFrom - аналог обычной recvfrom как я понимаю. Работает на дейтаграммах, без установления соединения. У Владислава сделана задержка (как я понял) для того, чтобы с учетом задержки ответа не вызывать в каждом цикле ПЛК SysSockRecvFrom.
Но Ваш вариант в общем мне больше нравится. Но ПК все равно не отвечает (см.скрин) - если это файерволл ПК, то почему обычный пинг с ПК на ПЛК проходит*. И кстати, Вас не смущает, что первые четыре байта (30 31) (32 33) приходят в поле идентификатора и порядкового номера?1762917630

Yegor
09.04.2015, 13:16
Что значит "поточные"? SysSockRecvFrom - аналог обычной recvfrom как я понимаю.«Поточные» в широком смысле — вместе с теми, которые пишут и читают в/из последовательного порта, например. Насколько я знаю, recvfrom блокирует поток в ожидании данных. Но я слишком давно ничего не писал голыми сокетами в нативных языках на ПК, чтобы утверждать наверняка. Это же касается и полей-идентификаторов. Полагаю, их надо заполнять вручную. Однако факт есть факт — на моей машине оно работает и с такими идентификаторами.

sgmj
09.04.2015, 14:01
«Поточные» в широком смысле — вместе с теми, которые пишут и читают в/из последовательного порта, например. Насколько я знаю, recvfrom блокирует поток в ожидании данных. Но я слишком давно ничего не писал голыми сокетами в нативных языках на ПК, чтобы утверждать наверняка. Это же касается и полей-идентификаторов. Полагаю, их надо заполнять вручную. Однако факт есть факт — на моей машине оно работает и с такими идентификаторами.

Спасибо еще раз за пример. Разобрался - проблема в самом деле в брандмауэре - он пропускал только ответы на запросы встроенной в Windows утилиты ping. Ответы на ICMP пакеты других программ блокировались.

Все работает, но мне все таки странно видеть данные из буфера "данных" в качестве идентификатора...
Ну и непонятно использование структуры SOCKADDRESS - зачем у Владислава в примере задается порт sock_adr1.sin_port:=16#1111 ?

Yegor
09.04.2015, 15:44
Ну и непонятно использование структуры SOCKADDRESS - зачем у Владислава в примере задается порт sock_adr1.sin_port:=16#1111 ?Тот, кто это писал, не понимал назначения этой структуры. В неё ничего записывать не надо, т.к. туда пишет координаты отправителя функция RecvFrom.

sgmj
09.04.2015, 17:53
А кстати, в чем смысл:

IF stateTimer.ET > T#1s AND state < C_ERROR THEN
state := C_ERROR + state;
END_IF
?

И сокет не закрывается потому, что пинг бесконечный?

Yegor
09.04.2015, 19:01
Там выше ещё строка есть stateTimer(IN := state = _state). С таким таймером мы знаем, в течение какого времени находимся на текущем шаге. Соответственно те строки, про которые вы спросили, переводят автомат в состояние ошибки, если мы топчемся на одном шаге дольше секунды. Например, если не дождались ответа (шаг 3), то выставляется код/состояние 203. Если по какой-то причине не смогли даже скормить ответ на отправку, то код будет 202. При отладке очень помогает. Этот же таймер и для выдерживания пауз используется (состояние SUCCESS). Ну и вообще это у меня идиома такая для конечных автоматов на ST.

Да, сокет не закрывается, потому что этот код кроме бесконечной демонстрации пинга ничего не делает.

Филоненко Владислав
10.04.2015, 08:49
Ну и непонятно использование структуры SOCKADDRESS - зачем в примере задается порт sock_adr1.sin_port:=16#1111 ?

Сделано это для целей отладки - видимо создатель программы по шагам проверял работу всех функций (писал не я, могу только догадываться).
P.S. Требовать от примера Ping совершенства, отсутствия синтаксического оверхеда, развёрнутых комментариев и тотальной обработки ошибок - это перфекционизм. :D

Rednaxel
31.10.2017, 18:08
Здравствуйте!
Оформил упомянутый в теме ICMP_TEST_PING.pro в виде блока, который после 4-х подряд успешных запросов показывает что устройство в сети:
33941
Используется ПЛК 110.60 старой серии.
Блок работает, но только когда он в одном экземпляре, что впрочем вполне ожидаемо.
По условиям задачи нужно отслеживать появление в сети 10-ти устройств с идущими подряд IP адресами, но при этом нужно знать какое именно устройство появилось в сети и какое отключилось.
Напрашивается мысль что нужно перебирать в блоке адреса по очереди, но моего опыта в ST маловато для решения подобной задачи, к тому же отлаживать приходится на "боевом" ПЛК и случаются зависания.

Подскажите пожалуйста, как примерно должен выглядеть код, реализующий такую задачу, или может быть есть другой алгоритм?