Форум: Форум PHPФорум ApacheФорум Регулярные ВыраженияФорум MySQLHTML+CSS+JavaScriptФорум FlashРазное
Новые темы: 0000000
Программирование. Ступени успешной карьеры. Авторы: Кузнецов М.В., Симдянов И.В. Самоучитель PHP 5 / 6 (3 издание). Авторы: Кузнецов М.В., Симдянов И.В. Объектно-ориентированное программирование на PHP. Авторы: Кузнецов М.В., Симдянов И.В. Социальная инженерия и социальные хакеры. Авторы: Кузнецов М.В., Симдянов И.В. MySQL на примерах. Авторы: Кузнецов М.В., Симдянов И.В.
ВСЕ НАШИ КНИГИ
Консультационный центр SoftTime

Форум PHP

Выбрать другой форум

 

Здравствуйте, Посетитель!

вид форума:
Линейный форум Структурный форум

тема: Разбить последовательность чисел на диапазоны и выбросить лишние диапазоны
 
 автор: Proton   (06.03.2013 в 20:20)   письмо автору
 
 

Здравствуйте.

Есть ряд коммутаторов, на которые заходит скрипт по SNMP и получает некую полезную информацию. Порой коммутаторы выходят из строя и заменяются на новые, с новым IP, таким образом часть IP адресов из подсети которая назначена коммутаторам просто недоступны. Скрипт, когда встречает такой IP, берёт тайм-аут в секунду, за тем понимает, что коммутатор с таким IP не доступен и двигается дальше по диапазону IP адресов обходя все остальные коммутаторы.

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

Вот код:
<?php

  
// Задаём диапазон IP адресов (подсеть 192.168.25.0/19)
  
$network_25 = array('start' =>  ip2long('192.168.25.0'), 'end' => ip2long('192.168.31.254'));

  
// Инициируем массив, в котором будем хранить IP активных коммутаторов
  
$address_ranges = array();

  
// В цикле обходим все коммутаторы и выясняем доступны ли они
  
for($i $network_25['start']; $i <= $network_25['end']; $i++)
  {
    
// Преобразуем число обратно в IP
    
$ip_dlink long2ip($i);

    
// Проверяем доступность коммутатора
    
$fp = @fsockopen($ip_dlink'23'$errno$errstr1);
    if (!
$fp)
    {

     
// Здесь код который делает все хорошо

    
}
  }
?>


Необходимо массив $address_ranges с помощью кода "// Здесь код который делает все хорошо" привести к виду:

$address_ranges = array(
                         array('start' =>  ip2long('192.168.25.145'), 'end' => ip2long('192.168.25.146')),
                         array('start' =>  ip2long('192.168.25.150'), 'end' => ip2long('192.168.25.219')),
                         array('start' =>  ip2long('192.168.25.221'), 'end' => ip2long('192.168.25.254')),
                         array('start' =>  ip2long('192.168.26.1'),   'end' => ip2long('192.168.26.254')),
                         array('start' =>  ip2long('192.168.27.1'),   'end' => ip2long('192.168.27.254')),
                         array('start' =>  ip2long('192.168.28.1'),   'end' => ip2long('192.168.28.239')),
                         array('start' =>  ip2long('192.168.29.241'), 'end' => ip2long('192.168.29.254'))
                      );


Есть идеи, как такое провернуть?

Решить задачу в лоб в принципе, с начала, кажется не сложно. Необходимо выставить некий флаг, который показывает, что сейчас код "// Здесь код который делает все хорошо" натыкается на недоступные IP (ну ещё бы 192.168.25.0 уж точно не доступен) и как только код "// Здесь код который делает все хорошо" наткнётся на доступный IP он должен сделать:

$address_ranges[$i]['start'] = $ip_dlink


и выставить флаг в положение я работаю с доступными IP, затем, как только код наткнётся на недоступный IP он должен сделать:

$address_ranges[$i]['end'] = $ip_dlink


и выставить флаг в положение я работаю с не доступными IP...

И вот тут начинаются проблемы $address_ranges[$i]['end'] будет присвоен IP недоступного коммутатора, а на самом деле надо присвоить предыдущий IP...

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

Подтолкните к правильному решению пожалуйста.

  Ответить  
 
 автор: Proton   (08.03.2013 в 09:31)   письмо автору
 
   для: Proton   (06.03.2013 в 20:20)
 

Ночь прошла и до меня дошло наконец как это должно выглядеть.

Мне нужен один массив содержащий только валидные IP. Его легко сгенерировать и легко обойти с помощью foreach. Это так же позволит мне избавиться от вложенного цикла.

  Ответить  
 
 автор: Proton   (08.03.2013 в 11:44)   письмо автору
 
   для: Proton   (08.03.2013 в 09:31)
 

Нифига себе!!! Время выполнения скрипта: 2.77 секунд

Знал, что время выполнения сократиться, но чтоб так!

Просто по сгенерированному массиву заведомо доступных коммутаторов скрипт проходится, вот и всё.

  Ответить  
 
 автор: Valick   (08.03.2013 в 12:37)   письмо автору
 
   для: Proton   (08.03.2013 в 11:44)
 

можно еще попробовать пинговать эти IP вдруг какой-то отвалился, и можно сделать unset()
при доступных IP вроде время особо не должно увеличиться, потеря времени как раз составляла на недоступных IP
ping с теми параметрами которые я указал в скрипте, в два раза быстрее чем проверка через
$fp = @fsockopen($ip_dlink, '23', $errno, $errstr, 1);

  Ответить  
 
 автор: Proton   (08.03.2013 в 13:27)   письмо автору
 
   для: Valick   (08.03.2013 в 12:37)
 

unset() тоже хорошая. Пожалуй воспользуюсь ею.

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

<?php
function test_dlink_connection($ip_dlink)
  {
    
$socket  socket_create(AF_INETSOCK_STREAMSOL_TCP);
    
socket_set_block($socket);
    
socket_set_option($socketSOL_SOCKETSO_RCVTIMEO, array('sec'=>0'usec'=>30000));
    
socket_set_option($socketSOL_SOCKETSO_SNDTIMEO, array('sec'=>0'usec'=>30000));
    
$test = @socket_connect($socket$ip_dlink23);
    
socket_close($socket);
    return 
$test;
  }

?>


Вроде работает...

  Ответить  
 
 автор: Valick   (08.03.2013 в 16:04)   письмо автору
 
   для: Proton   (08.03.2013 в 13:27)
 

ну кто быстрее тот и в коде :)

  Ответить  
 
 автор: Proton   (08.03.2013 в 16:38)   письмо автору
 
   для: Valick   (08.03.2013 в 16:04)
 

Ну вот этот вариант походу и быстрее.

  Ответить  
 
 автор: Igorek   (08.03.2013 в 09:45)   письмо автору
 
   для: Proton   (06.03.2013 в 20:20)
 

Если проблема только в этом:
>И вот тут начинаются проблемы $address_ranges[$i]['end'] будет присвоен IP недоступного коммутатора, а на самом деле надо присвоить предыдущий IP...

то, что вам мешает сделать:
<?php
$address_ranges
[$i]['end'] = long2ip(ip2long($ip_dlink)-1);

  Ответить  
 
 автор: Igorek   (08.03.2013 в 09:47)   письмо автору
 
   для: Igorek   (08.03.2013 в 09:45)
 

точнее даже:
<?php 
$address_ranges
[$i]['end'] = long2ip($i-1);

  Ответить  
Rambler's Top100
вверх

Rambler's Top100 Яндекс.Метрика Яндекс цитирования