Что нового

Упростить цикл запуска пингов, возможно с помощью рекурсии

DyadyaGenya

Знающий
Сообщения
300
Репутация
10
Доброго времени суток. Если только запускать пинг на перечень адресов, и вывести отчет по отсутствующим адресам, то это вроде как легко. Но вот запустить несколько пингов подряд на один адрес для подстраховки, вдруг был маленький случайный сбой, у меня получается кривовато. По идее можно было бы решить вопрос рекурсией, но не могу придумать как это сделать:
Код:
Global Const $CSVFILE = @ScriptDir & '\spisok_host.txt'
_ProverPing()
Func _ProverPing()
Local $res = _FileReadToArray($CSVFILE, $arrContent)

If $res = 1 Then
    For $i = 1 To $arrContent[0]
        $arrLine = StringSplit($arrContent[$i], $DELIM)
        If IsArray($arrLine) And $arrLine[0]<>0 Then
            Local $input = $arrLine[1] & "|" & $arrLine[2]
            _ArrayAdd($aPing, $input)
        Else
            MsgBox(48, "", "Ошибка в разбитии линии!")
        EndIf
    Next
Else
    MsgBox(48, "", "Ошибка открытия файла!")
 EndIf
 ;_ArrayDisplay($aPing)
EndFunc

 _PingKomp()
 Func _PingKomp()
Local $hFile = FileOpen(@ScriptDir & "\Отчет по прохождению пингов.log", 1) ; Открывает лог-файл в режиме записи.

For $i = 0 to UBound($aPing)-1
Ping($aPing[$i][0], 400)
If Not @error Then ; также возможно:  If @error = 0 Then ...
    ConsoleWrite($aPing[$i][0] & " - " & $aPing[$i][1]  & "  хост онлайн" & @CR)
    Ping($aPing[$i][0], 400)
    If Not @error Then ConsoleWrite($aPing[$i][0] & " - " & $aPing[$i][1]  & "  хост онлайн" & @CR)
       Ping($aPing[$i][0], 400)
If Not @error Then ConsoleWrite($aPing[$i][0] & " - " & $aPing[$i][1]  & "  хост онлайн" & @CR)
   Ping($aPing[$i][0], 400)
   If Not @error Then ConsoleWrite($aPing[$i][0] & " - " & $aPing[$i][1]  & "  хост онлайн" & @CR)
Else
      _FileWriteLog($hFile, $aPing[$i][0] & " - " & $aPing[$i][1]  & "  не доступен") ; Записывает в лог-файл передавая дескриптор возвращённый функцией FileOpen.
      Ping($aPing[$i][0], 400)
      If @error Then Ping($aPing[$i][0], 400);_FileWriteLog($hFile, $aPing[$i][0] & " - " & $aPing[$i][1]  & "  не доступен")
      If @error Then Ping($aPing[$i][0], 400) ;_FileWriteLog($hFile, $aPing[$i][0] & " - " & $aPing[$i][1]  & "  не доступен")
      If @error Then _FileWriteLog($hFile, $aPing[$i][0] & " - " & $aPing[$i][1]  & "  не доступен")
 EndIf
 Next
_FileWriteLog($hFile, "----------------------------")
 FileClose($hFile) ; Закрывает дескриптор, освобождая файл.
 EndFunc

На всякий случай список адресов пишется в формате: адрес|имя хоста
 

All2khoff

Продвинутый
Сообщения
351
Репутация
65
у кого-то из форумчан подсмотрел и отныне я делал такую схему проверки ответа от адресата.
Код:
if ping ($aPing) or ping ($aPing)
 
Автор
D

DyadyaGenya

Знающий
Сообщения
300
Репутация
10
у кого-то из форумчан подсмотрел
Не совсем понял пример. И возможно не прав, что забыл уточнить. Мне ж нужно, чтоб результат записывался в файл/консоль по 4 пинга на каждый адрес. А в вашем примере, как я понимаю, есть только проверка дважды, или сколько раз повторим альтернативу после OR. Напр., у меня 4 раза:
Код:
Func _PingKomp()
 For $i = 0 to UBound($aPing)-1
    If ping($aPing) or ping($aPing) or ping($aPing) or ping($aPing) Then
      ConsoleWrite($aPing[$i][0] & " - " & $aPing[$i][1] & @CR)
    EndIf
 Next
EndFunc
 

All2khoff

Продвинутый
Сообщения
351
Репутация
65
нужно чтобы если первый пинг не прошел проверить еще 3 раза, и на каждый пинг "с неудачей" делалась запись в журнал?


или чтобы каждый хост независимо от результатов проверялся 4 раза?
 
Автор
D

DyadyaGenya

Знающий
Сообщения
300
Репутация
10
нужно чтобы если первый пинг не прошел проверить еще 3 раза, и на каждый пинг "с неудачей" делалась запись в журнал?
Да, в отдельный файл успешные и не успешные. В шапке я сделал при успешном пинге запись в консоль, а при не успешном в файл, но это не важно, куда пишет.
 

All2khoff

Продвинутый
Сообщения
351
Репутация
65
Я вижу это как-то так.
Код:
_PingKomp()
Func _PingKomp()
   Local $hFile = FileOpen(@ScriptDir & "\Отчет по прохождению пингов.log", 1) ; Открывает лог-файл в режиме записи.
For $i = 0 to UBound($aPing)-1
   For 1 to 4
      Ping($aPing[$i][0], 400)
      If Not @error Then ; также возможно:  If @error = 0 Then ...
         ConsoleWrite($aPing[$i][0] & " - " & $aPing[$i][1]  & "  хост онлайн" & @CR)
      Else
         ConsoleWrite($aPing[$i][0] & " - " & $aPing[$i][1]  & "  хост оффлайн" & @CR)
   Next
Next
   _FileWriteLog($hFile, "----------------------------")
   FileClose($hFile) ; Закрывает дескриптор, освобождая файл.
EndFunc
 
Автор
D

DyadyaGenya

Знающий
Сообщения
300
Репутация
10
Я вижу это как-то так
К сожалению не работает. Выдавал ошибку цикла, переписал так:
Код:
Func _PingKomp()
   Local $hFile = FileOpen(@ScriptDir & "\Отчет по прохождению пингов.log", 1) ; Открывает лог-файл в режиме записи.
For $i = 0 to UBound($aPing)-1
   For $j =1 to $j = 4
      $jPing[$j] = Ping($aPing[$i][0], 400)
      If Not @error Then ; также возможно:  If @error = 0 Then ...
         ConsoleWrite($aPing[$i][0] & " - " & $aPing[$i][1]  & "  хост онлайн" & @CR)
      Else
         ConsoleWrite($aPing[$i][0] & " - " & $aPing[$i][1]  & "  хост оффлайн" & @CR)
      EndIf
   Next
Next
   _FileWriteLog($hFile, "----------------------------")
   FileClose($hFile) ; Закрывает дескриптор, освобождая файл.
EndFunc

Но тоже не работает. Вернее функция запускается, но в лог ничего не пишется.
Пы.Сы. Да и по логике скорее всего не будет того результата, что нужен мне. Потому что по идее в таком коде будет первый раз подряд проверятся пинг на все адреса и запишется в лог, потом второй раз пройдется по всем адресам, потом третий и четвертый. Получится черезпослоица. А хочется результат типа этого:
Код:
192.168.0.10 - директор хост оффлайн
192.168.0.10 - директор хост оффлайн
192.168.0.10 - директор хост оффлайн
192.168.0.10 - директор хост оффлайн
192.168.0.11 - бухгалтер хост оффлайн
192.168.0.11 - бухгалтер хост оффлайн
192.168.0.11 - бухгалтер хост оффлайн
192.168.0.11 - бухгалтер хост оффлайн

Хотя на самом деле тут инетовские адреса пингуются ))) Но суть та же
 
Последнее редактирование:

All2khoff

Продвинутый
Сообщения
351
Репутация
65
К сожалению не работает. Выдавал ошибку цикла
прошу прощения за ошибку писал с телефона, так должно работать.
Код:
_PingKomp()
Func _PingKomp()
   Local $hFile = FileOpen(@ScriptDir & "\Отчет по прохождению пингов.log", 1) ; Открывает лог-файл в режиме записи.
For $i = 0 to UBound($aPing)-1
   For $a = 1 to 4
      Ping($aPing[$i][0], 400)
      If Not @error Then ; также возможно:  If @error = 0 Then ...
         ConsoleWrite($aPing[$i][0] & " - " & $aPing[$i][1]  & "  хост онлайн" & @CR)
      Else
         ConsoleWrite($aPing[$i][0] & " - " & $aPing[$i][1]  & "  хост оффлайн" & @CR)
   Next
Next
   _FileWriteLog($hFile, "----------------------------")
   FileClose($hFile) ; Закрывает дескриптор, освобождая файл.
EndFunc
 
Автор
D

DyadyaGenya

Знающий
Сообщения
300
Репутация
10
прошу прощения за ошибку писал с телефона, так должно работать.
Все нормально ) опечатки бывают у всех, у меня так они вообще постоянно ))) Этот вариант работает. Но тут тоже была опечатка ) Пропущен конец секции IF. Добавил EndIf и все стало работать.
Интересно, можно как-то отрегулировать, чтоб печатало скажем первый и последний результат цикла. Тоесть не 4 (1,2,3,4), а скажем 2 из 4, напр 1 и 4?
 

Oki

Продвинутый
Сообщения
452
Репутация
62
Интересно, можно как-то отрегулировать, чтоб печатало скажем первый и последний результат цикла. Тоесть не 4 (1,2,3,4), а скажем 2 из 4, напр 1 и 4?
Можно, конечно. Достаточно в условии добавить через логическую операцию And нужные дополнительные фильтры или поставить их в отдельных условных операторах If либо внутри, либо снаружи проверки результативности пинга. Но зачем тогда пинговать впустую второй и третий разы, если результаты не нужны? Если лень большой лог читать, то можно для каждого пинга его результативность сохранять в логической переменной, а на следующем пинге того же адреса выводить результат только в случае отличающейся результативности. Туда же несложно прикрутить счётчик количества повторов одинаковых результатов подряд для одного адреса. Или какая всё-таки цель этого вопроса? Может быть, логичнее вообще выводить не номера пингов с отказами и без, а поставить лишь счётчик количества отказов и после полного цикла пингов выводить только его значение, из которого будет следовать насколько результативны пинги по каждому адресу?
 
Последнее редактирование:
Автор
D

DyadyaGenya

Знающий
Сообщения
300
Репутация
10
Но зачем тогда пинговать впустую второй и третий разы, если результаты не нужны?
Ситуация теоретическая, но зачем писать лишние строки, раздувать файл логов, напр, если 2 и 3 пинги работают, то значит хост скорее всего доступен, только периодически что-то мешает достучаться (флуд или ещё что-то) и тогда по идее можно пометить как проблемный, но рабочий и не такой срочный. Если пингов нет вообще, то хоть 4 пинга, хоть 24 (регулируется в секции For $a = 1 to 4), в отчете он будет помечен как не работающий и требующий более быстрой реакции на устранение. Но эта хотелка у меня появилась в ходе работы над скриптом. Буду пробовать ваши подсказки. Если не получится, то выложу наиболее верный на мой взгляд вариант для критики и доработки.
 

All2khoff

Продвинутый
Сообщения
351
Репутация
65
во время отладки чем подробней пишем лог или в консоль тем лучше.
Но в дальнейшем, нужно будет просто сообщать о "критической ситуации", без излишеств и только по делу.
Как вариант считать по циклам, например 4 раза полностью пройден список адресов, а хост 192.168.88.12 недоступен, то записать в лог и отправить письмо на email, или в телеграмм.
Сообщение автоматически объединено:

Интересно, можно как-то отрегулировать, чтоб печатало скажем первый и последний результат цикла. Тоесть не 4 (1,2,3,4), а скажем 2 из 4, напр 1 и 4?
можно, просто включаем еще одну функцию со счетчиком недоступности узла.
Код:
global $a = 1

_PingKomp()
Func _PingKomp()
   Local $hFile = FileOpen(@ScriptDir & "\Отчет по прохождению пингов.log", 1) ; Открывает лог-файл в режиме записи.
For $i = 0 to UBound($aPing)-1
   For $a = 1 to 4
      Ping($aPing[$i][0], 400)
      If Not @error Then ; также возможно:  If @error = 0 Then ...
         ConsoleWrite($aPing[$i][0] & " - " & $aPing[$i][1]  & "  хост онлайн" & @CR)
      Else
         log($aPing[$i][0],$aPing[$i][1])
      EndIf
   Next
Next
   _FileWriteLog($hFile, "----------------------------")
   FileClose($hFile) ; Закрывает дескриптор, освобождая файл.
EndFunc

Func log($adres,$namepc)
   Select
   Case $a = 1        ; адрес первый раз недоступен
      $a = $a + 1    ;ничего не делаем но счетчик +1
   Case $a = 2        ;адрес второй раз недоступен
      $a = $a + 1    ;Записываем в дог 2ю запись и счетчик +1
      ConsoleWrite($adres & " - " & $namepc  & "  хост оффлайн" & @CR)
   Case $a = 3        ;адрес 3й раз недоступен
      $a = $a + 1    ;ничего не делаем но счетчик +1
   Case $a = 4         ;адрес 4й раз недоступен
      $a = 1        ;Записываем в дог 4ю запись и сбрасываем счетчик
      ConsoleWrite($adres & " - " & $namepc  & "  хост оффлайн" & @CR)
   Case Else
      ;чтото пошло не так но на всякий случай тоже сбрасываем счетчик
      ConsoleWrite("ошибка счетчика" & @CR)
      $a = 1
   EndSelect
EndFunc
 
Последнее редактирование:
Верх