Вниз
Скачать: 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 вся ветка

Скачать: CL | DM;



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


1-1229882763
mefodiy
2008-12-21 21:06
2010.02.07
Центрирование содержимого ячейки по вертикали в таблице Word


15-1259631921
brother
2009-12-01 04:45
2010.02.07
Far и команда Noop


2-1260503262
depot
2009-12-11 06:47
2010.02.07
использование TAction


2-1260268394
d@nger
2009-12-08 13:33
2010.02.07
Как получить результат SQL запроса (Firebird)




   Наверх