Главная страница
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.015 c
3-1234341518
TTLr
2009-02-11 11:38
2010.02.07
Экспорт таблицы


15-1259574196
картман
2009-11-30 12:43
2010.02.07
Большие таблицы


2-1260539849
Ху.рБуер
2009-12-11 16:57
2010.02.07
Загрузка файла по FTP (Indy)


15-1259877728
kyn66
2009-12-04 01:02
2010.02.07
Странно ветка исчезла.


4-1228799718
Skyle
2008-12-09 08:15
2010.02.07
Непонятки с USB сканером с эмуляцией COM. Не работает RXFLAG.