Определить конец HTTP-пакета - PullRequest
2 голосов
/ 15 сентября 2010

Я должен написать скрипт PHP, который работает как клиент против другого HTTP-сервера.Этот сервер игнорирует заголовок HTTP Connection: Close и сохраняет TCP-соединение открытым, если оно не закрыто клиентом.И вот моя дилемма.Я (клиент) должен решить, когда закончился HTTP-запрос / ответ, а затем закрыть соединение.Просто используйте:

$ data = file_get_contents ($ url);

.. не будет работать, так как file_get_contents возвращается только в случае тайм-аута соединения (по умолчанию 30 секунд)достиг.

Поэтому мне нужно написать свой собственный цикл чтения - вот так (псевдокод):

$sock = fsockopen(...);
$data = '';
while($line = fgets($sock)) {
    $data .= $line;
    if(http_package_recieved()) {
        break;
    }
}

К сожалению, в ответе нет заголовка Content-Length.У меня вопрос, как должна выглядеть функция

http_package_recieved()

...

Приветствует Торстена

Ответы [ 5 ]

3 голосов
/ 15 сентября 2010

Вы можете проверить, пуста ли строка $, чтобы увидеть, если сервер ничего не отправляет. Вы также можете установить небольшой тайм-аут чтения для сокета с помощью stream_set_timeout(), а затем внутри цикла проверить stream_get_meta_data(), чтобы увидеть, было ли оно достигнуто, чтобы выйти из строя.

2 голосов
/ 15 сентября 2010

Если он не закрывает соединение и , он не сообщает вам общую длину ответа, у вас нет возможности узнать, все ли данные были получены.

Вы можете указать максимальный интервал времени между пакетами, но это не будет надежным.

2 голосов
/ 15 сентября 2010

Для этого лучше использовать библиотеку, например cURL (http://uk.php.net/manual/en/intro.curl.php),. Спецификация HTTP не проста: http://tools.ietf.org/html/rfc2616 (см. Раздел 4.4), и вы скорее всего пропущу что-то важное.

1 голос
/ 15 сентября 2010

Когда сущность заканчивается, либо руководствуется:

  • Content-Length заголовок (которого у вас нет)
  • HTTP Chunked Transfer Encoding (см. Заголовок Transfer-Encoding: chunked: у вас есть один из них?).

Возможно, вам придется обработать эту кодированную кодировку передачи, если вы получите этот заголовок. Для этого есть библиотеки.

0 голосов
/ 15 сентября 2010

feof($sock) будет в порядке

...