fsockopen и stream_set_timeout

dilan

Новичок
fsockopen и stream_set_timeout

Почему при установке
PHP:
stream_set_timeout($fp, 0)
на нуль процесс чтения все равно происходит....
PHP:
$fp = fsockopen("www.somehost.ru", 80);
if (!$fp) {
    echo "Unable to open\n";
} else {

    fwrite($fp, "GET / HTTP/1.0\r\n\r\n");
    stream_set_timeout($fp, 0);
    
    while ( !feof( $fp ) ) { 
			    $body .= fread( $fp, 256 );
    }

    $info = stream_get_meta_data($fp);
    fclose($fp);

    if ($info['timed_out']) {
        echo 'Connection timed out!';
    } else {
        echo $body;
    }

}
Спасибо.
 

white phoenix

Новичок
а почему оно не должно происходить?
все сокеты делятся на блокирующие и неблокирующие, блокирующие это те у которых timeout больше нуля, а неблокирующие это те у которых оный равен нулю.
разберем механизм передачи данных... я думаю ты уже знаешь что соеденения происходят на определенный порт (между портами с двух сторон), и т.д. на низком уровне сокетами управляет ОС, она складывает данные в буфер соеденения и т.д., но это сейчас не так важно. Если не указывать
PHP:
stream_set_timeout($fp,0);
то fread будет ждать данные из буфера (которые в сокет придут) размером не менее заданной длины (в твоем примере 256) либо пока не придет EOF (END OF FILE). если timeout установлен в значение больше 0, то fread ждет данные по такой же схеме, но по истечению timeout функция вернет FALSE. если timeout = 0, то fread посмотрит пришли ли данные и если не пришли в полном обьеме (и/или не пришел EOF) то вернет FALSE.
Теория закончена, теперь к практике. Когда исполняется приведенный в твоем посте код, fread не ждет данные и не блокирует работу скрипта до их прихода. Тем не менее feof($fp) возвращает FALSE т.к. EOF не пришел. Следовательно у тебя должно происходить чтение. Оно бы не происходило если бы ты сделал
PHP:
      while ($buf = fread( $fp, 256 )) { 
                $body .= $buf; 
    }
В этом случае как только fread вернет FALSE, цикл прекратит работу.
 

dilan

Новичок
Спасибо большое.
Про то что fread() возврашает FALSE в случае достижения конца удаленного файла я не догнал...
Доступно объяснил.

-~{}~ 18.01.06 11:11:

про fread() это ты поторопился.... в каком мануале ты прочитал что при достижении конца файла fread() возвращает FALSE???
 

white phoenix

Новичок
dilan
Я не совсем точно выразился. При использовании fread ... == FALSE, будет истина, но при === FALSE - ложь.
В
PHP:
while ($buf = fread( $fp, 256 )) {  
                $body .= $buf;  
    }
Используется ==.
 

dilan

Новичок
white phoenix
Если я правильно понял ты предлагаешь
PHP:
while ($buf == fread( $fp, 256 ))) {  
                $body .= $buf;
}
Но при этом $buf просто напросто перестает содержать считанные байты...

В любом случае мой вопрос остается открытым, поскольку

Тем не менее feof($fp) возвращает FALSE т.к. EOF не пришел. Следовательно у тебя должно происходить чтение.
Из мануала feof=>

Если подключение, открытое при помощи fsockopen() не было закрыто сервером, feof() будет ждать достижения таймаута прежде чем вернуть TRUE. Время таймаута по умолчанию равно 60 секундам. Вы можете использовать stream_set_timeout() для того, чтобы изменить это значение.

Такое впечатление что ошибочно, feof() устанавливает таймаут до default = 60 сек
white phoenix Если будут какие либо мысли по этому поводу пиши. Cпасибо за дискуссию :)
 

SiMM

Новичок
> Если будут какие либо мысли по этому поводу
1. Connection: close в запросе.
2. Брать длину ожидаемого контента из хидеров отклика, а не полагаться только на feof
 

white phoenix

Новичок
dilan
> Если я правильно понял ты предлагаешь
Нет, ты понял неправильно. А какие могут быть тут мысли, всё очевидно.
 

dilan

Новичок
white phoenix
А какие могут быть тут мысли, всё очевидно.
Если ты так считаешь то запусти свой пример и посмотри что будет... или напиши что ты имел ввиду .
Сдается мне ты с этой проблемой и не сталкивался, а сейчас кидаешься фразами
 
Сверху