Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2010.02.07;
Скачать: CL | DM;

Вниз

Особенности функции feof в php под windows.   Найти похожие ветки 

 
Дмитрий С ©   (2009-12-01 09:52) [0]

В документации по php для функции fsockopen приведен такой пример:

$fp = fsockopen("www.example.com", 80, $errno, $errstr, 30);
if (!$fp) {
   echo "$errstr ($errno)<br />\n";
} else {
   $out = "GET / HTTP/1.1\r\n";
   $out .= "Host: www.example.com\r\n";
   $out .= "Connection: Close\r\n\r\n";
   fwrite($fp, $out);
   while (!feof($fp)) {
       echo fgets($fp, 128);
   }
   fclose($fp);
}


Этот пример был взят в основу моего кода. Но на удивление сервер НЕ всегда возвращал весь результат.

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

Сейчас я думаю, что причина в ошибке реализации функции feof для сетевых потоков. Она возвращает true, после того как получен пакет о разъединении, а не когда буфер чтения пуст.

Вспомнилось из опыта, что функция recv (fread в php) возвращает пустой результат в случае если поток окончен (буфер чтения пуст и соединение закрыто), поэтому код был исправлен таким образом:


$fp = fsockopen("www.example.com", 80, $errno, $errstr, 30);
if (!$fp) {
   echo "$errstr ($errno)<br />\n";
} else {
   $out = "GET / HTTP/1.1\r\n";
   $out .= "Host: www.example.com\r\n";
   $out .= "Connection: Close\r\n\r\n";
   fwrite($fp, $out);
   $packet="A";
   while (strlen($packet)>0) {
       $packet = fread($fp, 128);
       echo $packet;
   }
   fclose($fp);
}


После этих изменений страница всегда получалась от сервера полностью.

Речь, конечно, не о delphi, но все же. Кто-нибудь прокомментируйте этот факт.
Вопросы:
1. Это действительно особенность Windows, или под Linux-ом поведение функции feof аналогичное?
2. Корректен ли второй вариант примера?
3. Ваши вопросы.


 
McSimm ©   (2009-12-01 10:03) [1]

Аналогичное поведение под Linux.
Для HTTP обычно длина берется либо из заголовка Content-Length, либо тело читается чанками, для каждого чанка сервер также отдает длину.


 
Дмитрий С ©   (2009-12-02 04:15) [2]


> McSimm ©   (01.12.09 10:03) [1]
>
> Аналогичное поведение под Linux.
> Для HTTP обычно длина берется либо из заголовка Content-
> Length, либо тело читается чанками, для каждого чанка сервер
> также отдает длину.

Забыл поправить примеры. У себя я использовал http/1.0. Когда длина страницы неизвестна, сервер обрывает соединение, обозначая тем самым ее конец.
И получается, что feof возвращает true, когда соединение разорвано, но данные в буфере для чтения еще есть и их можно прочитать.
Меня интересует именно эта особенность.



Страницы: 1 вся ветка

Текущий архив: 2010.02.07;
Скачать: CL | DM;

Наверх




Память: 0.47 MB
Время: 0.011 c
15-1259933827
Insor
2009-12-04 16:37
2010.02.07
Где взять компонент TrxTrayIcon отдельно только его?


2-1260419453
novai
2009-12-10 07:30
2010.02.07
Парсер строки


6-1211467897
vav
2008-05-22 18:51
2010.02.07
ActiveForm и TserverSocket


2-1260698706
Игорь
2009-12-13 13:05
2010.02.07
Определить имеет ли пользователь привилегии администратора


2-1260564996
DIM
2009-12-11 23:56
2010.02.07
Не понятно откуда берется такое значение переменной