За последние 24 часа нас посетили 18016 программистов и 1651 робот. Сейчас ищут 1778 программистов ...

cURL: прервать выполнение задания по таймауту

Тема в разделе "PHP для новичков", создана пользователем Ландух, 31 июл 2008.

  1. Ландух

    Ландух Активный пользователь

    С нами с:
    15 янв 2008
    Сообщения:
    5
    Симпатии:
    0
    Сразу скажу, что это не помогло:
    http://php.ru/forum/viewtopic.php?t=10165&highlight=curl+%F2%E0%E9%EC%E0%F3%F2

    Второй день бьюсь, никак победить не могу... помогите, кто чем может :)

    Значит, общая задача: сделать прокси-чекер.
    Споткнулся почти сразу же. Вот что удалось наваять:

    (php5):
    PHP:
    1. $started = time();
    2. // ... - тут прием и обработка переменных из запроса, думаю не интересно...
    3.  
    4. // checking proxies:
    5. $proxy_list = explode("\n", str_replace("\r", '', $proxylist));
    6. $proxy_count = count($proxy_list);
    7. $curl_common_opt = array(CURLOPT_URL => $dest_host.'/test.php',
    8.                      CURLOPT_RETURNTRANSFER => 1,
    9.                      CURLOPT_HEADER => false,
    10.                      //CURLOPT_LOW_SPEED_LIMIT => 2048,
    11.                      //CURLOPT_LOW_SPEED_TIME => 10,
    12.                      CURLOPT_TIMEOUT => 30,
    13.                      //CURLOPT_CONNECTTIMEOUT => 10,
    14.                      CURLOPT_USERAGENT => 'Some agent',
    15.                      CURLOPT_POST => 1,
    16.                      CURLOPT_PROXYTYPE => CURLPROXY_SOCKS5
    17.                     );
    18. $curl_master = curl_multi_init();
    19. $curl_handlers = array();
    20.  
    21. for ($i = 0; $i < $proxy_count; $i++)
    22. // preparing multi curl task:
    23. {
    24.     $curl_handlers[$i] = curl_init();
    25.     curl_setopt_array($curl_handlers[$i], $curl_common_opt +
    26.                             array(CURLOPT_PROXY => $proxy_list[$i],
    27.                                 CURLOPT_PROXYUSERPWD => "user:password",
    28.                                 CURLOPT_POSTFIELDS => 'command=Test'
    29.                                     ));
    30.     curl_multi_add_handle($curl_master, $curl_handlers[$i]);
    31. }
    32.  
    33. $going = $proxy_count;
    34. do
    35. // implementing multi curl task:
    36. {
    37.     if (@file_exists(DIR_CONTROLERS."/stop")) die('Manual stop');
    38.  
    39.     curl_multi_exec($curl_master, $running);
    40.     if ($running < $going)
    41.     {
    42.         echo ($going-$running)." proxy test completed. now testing ".$running." proxies<br>\n";
    43.         $going = $running;
    44.     }
    45.     sleep(2);
    46.     echo "prx_cnt: ($running); time: ".time()."<br>\n";
    47. }
    48. while ($running > 0);
    49.  
    50. for($i = 0; $i < $proxy_count; $i++)
    51. // capturing multi task results:
    52. {
    53.     $result = curl_multi_getcontent($curl_handlers[$i]);
    54.     if (curl_errno($curl_handlers[$i]) || $result != 'Test OK')
    55.     // if page was not got (proxy down):
    56.     {
    57.         if ($show_report) echo "Proxy ".$proxy_list[$i]." is down<br>\n";
    58.         echo curl_error($curl_handlers[$i])."<br>\n";
    59.         echo $result."<br>\n---------------------<br>\n";
    60.         unset($proxy_list[$i]);
    61.     }
    62.     curl_multi_remove_handle($curl_master, $curl_handlers[$i]);
    63.     curl_close($curl_handlers[$i]);
    64. }
    65. $proxy_list = array_merge($proxy_list, array());
    66. echo "test took ".(time()-$started)." sec.<br>\n";
    67. if (!count($proxy_list)) die("All proxies are down<br>\n");
    68.  
    69. die('test completed');
    70.  
    p.s. $dest_host в данном случае тот же, на котором размещен скрипт.

    Скрипт очень хорошо работает, если все прокси рабочие :) Проверка занимает около 20 секунд.

    Трабл в следующем, как только один падает - время выполнения затягивается на 60-100 секунд. Причем зависание происходит на второй итерации цикла "implementing multi curl task", в строке "curl_multi_exec($curl_master, $running);". Как я понимаю, он наталкивается на нерабочий прокси, долбится к нему битых полторы минуты, и потом продолжает цикл. И тут - ох ты! оказывается тайм-аут то наступил еще Бог весть когда... так что (ха-ха) курл со спокойной совестью сообщает мне об этом занимательном факте. Мол, я тут полчаса пытался отправить запрос, но таймаут-то 30 секунд, так что - извини - ошибочка!

    Внимание - вопрос! Как заставить его прекращать попытки соединения сразу же после наступления таймаута?
     
  2. Ландух

    Ландух Активный пользователь

    С нами с:
    15 янв 2008
    Сообщения:
    5
    Симпатии:
    0
    блин, табуляция все-таки поползла в коде... :(