Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > PHP: Общие вопросы > Как в php определить, есть ли соединение?


Автор: kanaris 1.7.2010, 22:30
Код

$sock=fsockopen('localhost',80);

$buf='';
fwrite($sock,"GET / HTTP /1.1\r\nHost: localhost\r\nConnection: close\r\n\r\n");
while(!feof($sock))$buf.=fgets($sock);


После отправки запроса и получения ответа соединение сервер закрывает. А вот дескриптор $sock все еще остается жив.
Есть ли какие-нибудь способы проверить, закрылось ли соединение? 

Автор: Kano 1.7.2010, 23:08
Запрос неправильный.

Автор: ksnk 1.7.2010, 23:13
может так?
Код

while(!feof($sock))$buf.=fgets($sock);

Автор: kanaris 1.7.2010, 23:18
Цитата

Запрос неправильный. 


Ну это к примеру, написал от руки, пока постил вопрос. (ну да, не стоит \r\n\r\n в конце, забыл).
В принципе, пока вы отвечали, проблему удалось решить "хирургическим" методом, посылая данные и запрашивание ответа. Если ошибка, значит не соединено и переподключается.

Но хотелось бы это выявить какими-нибудь цивилизованными методами (если бы существовала какая-нить функция "is_socked_connected($sock)" к примеру)

UPD:

Цитата

может так?
Код

while(!feof($sock))$buf.=fgets($sock);



Прошу простить мелкие опечатки, писал от руки для простого примера, может еще что-то забыл добавить, не важно (в оригинале все правильно и с этим проблем нет).

Автор: Kano 1.7.2010, 23:38
kanaris, такого в общем-то нет. Обычно это делается с помощью таймаута, т.е. создаётся неблокирующие сокеты и проверяются готов ли он к чтению/записи после определённого времени...

Зачем тебе это требуется в данном случае?

P.S. HTTP/1.1 нежелательно использовать в таких запросах. 

Автор: kanaris 1.7.2010, 23:54
Делаю класс, при помощи которого можно получить несколько веб-страниц за одно соединение. Все в принципе работает, но хотел еще добавить 1 функцию, которая бы объединяла в себе 3 действия (соединить, отправить, получить). А раньше приходилось делать так:

Код

$httpsock=new httpSocket;
$httpsock->connect('example.com:80',10);// 10 - это таймаут
$httpsock->send('/index.php',null,null,array('Connection'=>'keep-alive','Keep-Alive'=>'30'));// гет, пост, файлы, доп. хттп-заголовки
$r=$httpsock->readAll(); // возвращает массив: headers=>'заголовки',body=>'тело'
$httpsock->send('/index2.php');
$r=$httpsock->readAll();
if(!$httpsock->connect('example.com:80',10))die();// снова соединяемся, т.к. по умолчанию сервер закрывает соединение, если не указать Connection: keep-alive
$httpsock->send('/index3.php',null,null,array('Connection'=>'keep-alive','Keep-Alive'=>'30'));// гет, пост, файлы, доп. хттп-заголовки
$r=$httpsock->readAll(); // возвращает массив: headers=>'заголовки',body=>'тело'



Теперь достаточно так:

Код

$httpsock=new httpSocket;
$httpsock->connect('example.com:80',10);
$r1=$httpsock->page('/index.php',null,null,array('Connection'=>'keep-alive','Keep-Alive'=>'30'));
$r2=$httpsock->page('/index2.php');
$r3=$httpsock->page('/index3.php',null,null,array('Connection'=>'keep-alive','Keep-Alive'=>'30'));

Автор: Kano 2.7.2010, 00:21
kanaris, я вижу полноценное решение только через функции http://ru2.php.net/manual/en/ref.sockets.php Плюс, как ты понимаешь, придётся делать полноценный анализ ответа (включая поддержку chunked encoding).

Автор: kanaris 4.7.2010, 16:27
Цитата

Плюс, как ты понимаешь, придётся делать полноценный анализ ответа (включая поддержку chunked encoding)


да понимаю, сделал и chukned и content-length, все работает (а остальное, если что-то там будет, тоже доделаю).
пока что проблему решил, как описал во 2 своем посте.

Автор: NewDima 5.7.2010, 08:21
Цитата(Kano @ 2.7.2010,  06:38)
P.S. HTTP/1.1 нежелательно использовать в таких запросах.

Аргументируйте

Автор: Kano 5.7.2010, 09:11
NewDima, с тем же chunked encoding разбираться (в любом случае), разбираться со сжатым контентом (не все сервера смотрят за Accept-Encoding) и т.п. По-моему, очевидно. Далеко не все понимают различий HTTP/1.0 и HTTP/1.1, когда пишут подобные "сырые" запросы.

Имеется ввиду не сам HTTP-запрос, а код запроса на PHP.

Автор: kanaris 5.7.2010, 22:41
Вся соль в том, что нужно делать несколько запросов за одно соединение. А http 1/0 не поддерживает такое, на сколько я знаю smile

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)