Принудительный таймаут в fsockopen (Как задать таймаут через прокси-сервер)

Тема в разделе "PHP", создана пользователем incognet, 23 авг 2009.

Статус темы:
Закрыта.
Модераторы: latteo
  1. incognet

    incognet Создатель

    Регистр.:
    17 сен 2007
    Сообщения:
    41
    Симпатии:
    4
    Здраствуйте, наткнулся на такую проблему как ограничить, задать тайм аут на время ожидания ответа от fsockopen.
    Опишу подробнее. Есть екрипт который поднимает сокет соединение через ПРОКСИ.
    Вот упрощенный вариант его.
    Код:
    $sock = fsockopen($proxy, $port, $errno, $errstr, 15);
    if ($sock) {
    	fputs($sock,"GET [url]http://www.google.ru/[/url] HTTP/1.0\r\nHost: [url]www.google.ru\r\nCache-Control:[/url] no-store \r\n\r\n");
    	if (feof($sock)) {
    		die(‘error’);
    	} else {
    stream_set_timeout($sock,15);
    		$tmp='';
    		while (!feof($sock)) {
    			$tmp .= fgets($sock, 512);
    		}
    		die($tmp);
    	}
    	@fclose($sock);
    }
    И вот тут возникает проблема если не удалось подключиться к прокси-серверу то срабатывает таймаут в 15 сек. Но если к прокси-серверу подключение нормальное а у этого прокси-сервера самого проблемы с подключением к интернету, то выходит что скрипт начинает ждать какой-то невменяемый таймаут в несколько минут пока сам прокси-сервер не скажет “не могу”.
    Попытался задать stream_set_timeout($sock,15); но это нефика не помогает он продолжает честно ожидать пока прокси-сервер не скажет отбой.
    Вот вопрос как принудительно ограничить время ожидания. Если прокси-сервер такой оптимист что может ожидать несколько минут то это не приемлемо для скрипта. Надо чтоб скрипт через секунд 15 перестал ждать ответа от прокси-сервер и забил на него.
    Не кто не сталкивался с такой проблемой, как её можно решить?
    Заранее спасибо.
     
  2. tostrss

    tostrss

    Регистр.:
    16 окт 2007
    Сообщения:
    771
    Симпатии:
    217
    Используй курл.
     
  3. PapaJoe

    PapaJoe

    Регистр.:
    4 авг 2008
    Сообщения:
    620
    Симпатии:
    311
    Если вы делали по примеру php.net, http://ru2.php.net/stream_set_timeout то там пример для прямого соединения, а не через прокси.
    Быть может стоит поставить stream_set_timeout($sock,15); перед fputs(......); ?
     
  4. incognet

    incognet Создатель

    Регистр.:
    17 сен 2007
    Сообщения:
    41
    Симпатии:
    4
    попробовал stream_set_timeout($sock,15) перед fputs() бесполезно оно ждет ответа от прокси если токовая мертво то очень долго а на той прокси таймаут 3 минуты вот он и ждет 3 мин.
    а с curl()-ол надо попробовать если не получится с fsockopen()

    ---------- Post added at 02:55 ---------- Previous post was at 01:17 ----------

    мдя, забил на fsockopen() и сделал за 10 минут на курле, если кому вдруг понадобится рабочий пример, то вот он это прекрасно работает
    Код:
    	$ch = curl_init();
    	curl_setopt($ch, CURLOPT_URL, "http://www.google.ru/");
    	curl_setopt($ch, CURLOPT_PROXY , "{$proxy}:{$port}");
    	curl_setopt($ch, CURLOPT_HEADER, 0);
    	curl_setopt($ch, CURLOPT_TIMEOUT, 15);
    	curl_setopt($ch, CURLOPT_RETURNTRANSFER , 1);
    	curl_setopt($ch, CURLOPT_HTTPHEADER, Array("Cache-Control: no-store"));
    	$tmp = curl_exec($ch);
    	curl_close($ch);
    
     
  5. tostrss

    tostrss

    Регистр.:
    16 окт 2007
    Сообщения:
    771
    Симпатии:
    217
    На fsockopen это довольно частая проблема, поэтому все всегда ее решали через курл.
     
  6. incognet

    incognet Создатель

    Регистр.:
    17 сен 2007
    Сообщения:
    41
    Симпатии:
    4
    Да все в принципе логично тут не частая проблема а закономерная.
    У fsockopen() есть таймаут на коннект, если коннект поднялся то все прекрасно а когда начинаешь через этот коннект, с помощью заголовков идти на прокси а эта прокси сама отвалилась от интернета то происходит следующие. Коннект до прокси поднят (онаже жива), поэтому таймаут не сработает а прокся не может выйти сама в интернет, но этого не знаем же мы, соединение с проксей прекрасное, а прокся с интернетом не соединена. Поэтому в этом случае выходит что fsockopen() для этих целий вообще не приемлем, он хорош только для прямых подключений.
     
Статус темы:
Закрыта.