Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Perl: Общие вопросы > Как пропинговать хост


Автор: StealtH 23.9.2004, 22:19
Вот такой вопросик, есть код:

Код
if(&ping($host)){
print "Yes\n";
}else{
    print "No\n";}


sub ping($host)
{
use Net::Ping;
   $p=Net::Ping->new();
   $p->hires();
   ($ret, $duration, $ip) = $p->ping($host, 5.5);
    if($ret)
    {
      for ($i=0;$i<=$num_times;$i++)
      {
        $p->hires();
        ($ret, $duration, $ip) = $p->ping($host, 5.5);
        $ping_time+=$duration;
      }
      $ping_time=$ping_time/$i;
      $p->close();
      return 1;
    }else {
      $p->close();
      return 0;
}


так вот при $host='реально существующий хост' функция возвращает 0, в обратном случае тоже самое.
И второй вопрос:
при ответе пингуемого хоста время пинга $ping_time имеет очень жуткие значения, т.е. в 3-5 раз больше чем при пинге системной командой.

Помогите плиз, люди добрые, может где-то ошибочка или недоглядел чего.

Автор: korob2001 27.9.2004, 14:55
Цитата

так вот при $host='реально существующий хост' функция возвращает 0, в обратном случае тоже самое.

Попробуй такой вариант:
Код

#!/usr/bin/perl
my $host = "81.82.117.10";
my $num_times = 5;
if ( &pingNet( $host ) ){
    print "Yes\n";
} else {
    print "No\n";
}


sub pingNet {
   my $host = shift;
   use Net::Ping;
   my $p = Net::Ping->new();
      $p->hires();
   my( $ret, $duration, $ip ) = $p->ping( $host, 5.5 );
   if( $ret ) {
       for ( $i=0; $i<=$num_times; $i++) {
             $p->hires();
             ( $ret, $duration, $ip ) = $p->ping( $host, 5.5 );
             $ping_time += $duration;
       }
     $ping_time = $ping_time / $i;
     print "Ping time: $ping_time\n";
     print "-" x 80, "\n";
     $p->close();
     return 1;
   } else {
     $p->close();
     return 0;
   }
}

Обрати внимание на то, что в Perl в подпрограмме, в круглых скобках можно указать прототип. Тогда строка в которой создаётся подпрограмма, в нашем случает это pingNet, можно записать таким образом:
Код

sub pingNet($) {
      # Тело подпрограммы
}

Заметь что нельзя указывать в круглых скобках переменную которая получает параметр переданный подпрограмме, в нашем случае это переменная $host. В круглых скобках можно указать только прототип.
В противном случае, круглые скобки вообще не нужно указывать.

Все параметры которые ты передаёшь в подпрограмму можно получить в теле самой подпрограммы, обратившись к массиву @_.

Цитата

И второй вопрос:
при ответе пингуемого хоста время пинга $ping_time имеет очень жуткие значения, т.е. в 3-5 раз больше чем при пинге системной командой.

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

Удачи.

Автор: StealtH 28.9.2004, 17:54
Спасибо, попробую smile.gif

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


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


Автор: korob2001 28.9.2004, 23:14
Цитата

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

Попробуй модуль Benchmark или функцию times().

Если хочешь добиться максимальной быстроты, то просто скомпиль файл в .exe . Эксешник работает быстрее, но постарайся перед компиляцией максимально оптимизировать код, подключай по возможности как можно меньше модулей. Потому как, при компиляции Perl файла, в него компилица не только твоя програ с расширением .pl, но и сам инетрпритатор, а так же все подключаемые модули. От того файл .exe быстро набирает вес, что не есть гуд.
Желательно компилить большие проекты, почему объснять не буду, так как выше уже изложил, что происходит при компиляции.
Короче не стоит создавать .exe из проги "Hello, world!", так как к двум строкам кода:
Код

#!/usr/bin/perl
print "Hello, world!";

Добавится вес интерпритатора, естественно не всего, а только необходимых его частей. Это делается для того, что бы такой эксешник можно было запускать на машине, на которой не установлен интерпритатор Perl.

Удачи.

Автор: StealtH 28.9.2004, 23:42
Цитата(korob2001 @ 28.9.2004, 23:14)
Если хочешь добиться максимальной быстроты, то просто скомпиль файл в .exe . Эксешник работает быстрее

Так в том-то все и дело, что прога работает под линухом, в экзешник его не запихнешь.

У меня по этому поводу вознила идея: а не лучше ли будет пинговать системной командой, и вывод с нее перехватывать перловой прогой. Если есть вариант подскажи как, или подкинь ссылку на "человеческую" литературу, как это все проще сделать.

Автор: korob2001 29.9.2004, 00:05
Для вызова системной команды, юзай system(), но учти, что она просто выполнит системную команду но сохранить в переменной результат её выполнения, для дальнейшей обработки, у тебя не получится:
Код

#!/usr/bin/perl
use strict;
system( ls );


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

Пример:
Код

#!/usr/bin/perl
use strict;
my @dir = `ls`; # Кавычки обратные
foreach ( @dir ) {
   print $_, "\n";
}

По возможности старайся юзать system(), так как она более безопасна.

Удачи.

Автор: StealtH 30.9.2004, 01:55
Громадное спасибо, эти куски кода помогли сразу решить траблу не только с пингом, но и с многим другим, как только доделаю прогру обязательно поделюсь smile.gif

Начал юзать вспомнил еще один ньюанс: как запустить несколько процессов из скрипта, не дожидаясь пока процесс что-то возвратит thumbs-up.gif

Автор: korob2001 30.9.2004, 16:26
Посмотри доки по хешу %SIG. Помоему с его помощью управляют процессами. Ещё тебе может понадобиться функция fork().
perldoc -f fork

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)