Доброго времени суток. Вообщем выше описанна функция, отсылает ХТТП запрос ну и получает страницу. Так вот, пробовал получать страницы различных сайтов в итоге программа не доходя до конца страницы(всегда разное кол-во байт считанных от 9000 до 30000) зависала на read(видимо ждала остальные куски). Объясните... может я что не так делаю, что у меня в сокет приходит не вся страница? Ниже код GET запроса:
если я не забыл то нужно заключать Boost:asio:read не в цикл, а сначала узнавать размер пакета и записывать его в переменную, а потом уже по этой переменной считывать, это если сокет блокирующий, если не блокирующий будет то должно заработать.
Здравствуйте, Mazay, Вы писали:
M>Здравствуйте, st0nx, Вы писали:
M>Сначала сделай проверку на код ошибки в error. M>Потом свой логирующий функтор вместо transfer_at_least. M>Что такое len? M>Подозрительно выглядит код M>
M>rStr+=buf.data();
M>
M>buf.data() точно нулём заканчивается? Помоему нифига.
Написал такой функтор:
std::size_t HttpSendRecv_boost::read_hd(const boost::system::error_code &e,std::size_t bytes_transferred)
{
// где то тут я должен вернуть сколько байт надо прочитать и как то проверить залочится или нетif(!e)
{
std::cout << buf.data();
boost::asio::read(*socket,
boost::asio::buffer(buf),
boost::bind(&HttpSendRecv_boost::read_hd,this,boost::asio::placeholders::error,boost::asio::placeholders::bytes_transferred));
}
};
Здравствуйте, st0nx, Вы писали:
S>Здравствуйте, Mazay, Вы писали:
M>>Здравствуйте, st0nx, Вы писали:
M>>Сначала сделай проверку на код ошибки в error. M>>Потом свой логирующий функтор вместо transfer_at_least. M>>Что такое len? M>>Подозрительно выглядит код M>>
M>>rStr+=buf.data();
M>>
M>>buf.data() точно нулём заканчивается? Помоему нифига.
S>Написал такой функтор:
S>
S>Вопрос: Как я узнаю, что функция заблокируется? S>Такое сравнение: S>
S> e == boost::asio::error::would_block
S>
S>Ничего не дает
Какое отношение этот код имеет к первоначальной задаче?
Какая функция заблокируется? asio::read с функтором вообще никогда не блокируется, в этом же весь цимес.
Ты попробовал сделать то что я выше написал? Какие результаты?
Здравствуйте, Mazay, Вы писали:
M>Какое отношение этот код имеет к первоначальной задаче? M>Какая функция заблокируется? asio::read с функтором вообще никогда не блокируется, в этом же весь цимес. M>Ты попробовал сделать то что я выше написал? Какие результаты?
Видимо я не совсем понимаю, что есть функтор. Не могли бы вы, небольшим примером, подсказать? На boost.org среди примеров asio ничего подобного найти не могу.
Здравствуйте, st0nx, Вы писали:
S>Здравствуйте, Mazay, Вы писали:
M>>Какое отношение этот код имеет к первоначальной задаче? M>>Какая функция заблокируется? asio::read с функтором вообще никогда не блокируется, в этом же весь цимес. M>>Ты попробовал сделать то что я выше написал? Какие результаты?
S>Видимо я не совсем понимаю, что есть функтор. Не могли бы вы, небольшим примером, подсказать? На boost.org среди примеров asio ничего подобного найти не могу.
Здравствуйте, Mazay, Вы писали:
M>Здравствуйте, st0nx, Вы писали:
S>>Здравствуйте, Mazay, Вы писали:
M>>>Какое отношение этот код имеет к первоначальной задаче? M>>>Какая функция заблокируется? asio::read с функтором вообще никогда не блокируется, в этом же весь цимес. M>>>Ты попробовал сделать то что я выше написал? Какие результаты?
S>>Видимо я не совсем понимаю, что есть функтор. Не могли бы вы, небольшим примером, подсказать? На boost.org среди примеров asio ничего подобного найти не могу.
M>Функтор
Описание с boost.org:
completion_condition
The function object to be called to determine whether the read operation is complete. The signature of the function object must be:
std::size_t completion_condition(
// Result of latest read_some operation.const boost::system::error_code& error,
// Number of bytes transferred so far.
std::size_t bytes_transferred
);
A return value of 0 indicates that the read operation is complete. A non-zero return value indicates the maximum number of bytes to be read on the next call to the stream's read_some function.
Сделал все как там написанно (ошибок в "e" не бывает я проверял):
Итогом получил, то что приходит вся страница, а на последней итерации блокировка(а все потому, что я должен был вернуть 0 судя по ману. ) Так вот как узнать что данных в сокете больше нету?
S>Итогом получил, то что приходит вся страница, а на последней итерации блокировка(а все потому, что я должен был вернуть 0 судя по ману. ) Так вот как узнать что данных в сокете больше нету?
Уже лучше. TCP — это в первую очередь поток, у него нет понятия передаваемого объема.
Покажи HTTP запрос.
Здравствуйте, Mazay, Вы писали:
M>Здравствуйте, Mazay, Вы писали:
M>>Уже лучше. TCP — это в первую очередь поток, у него нет понятия передаваемого объема. M>>Покажи HTTP запрос.
M>И заголовки ответа тоже.
Вариант 1:
Request
GET / HTTP/1.1
Host: www.rsdn.org
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; ru; rv:1.9.1.16) Gecko/20101130 Firefox/3.5.16
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: ru-ru,ru;q=0.8,en-us;q=0.5,en;q=0.3
Accept-Encoding: gzip,deflate
Accept-Charset: windows-1251,utf-8;q=0.7,*;q=0.7
Connection: close
Response
HTTP/1.1 200 OK
Via: 1.1 FT02
Connection: close
Proxy-Connection: close
Content-Length: 1672
Date: Thu, 03 Mar 2011 06:17:38 GMT
Content-Type: text/html; charset=utf-8
Server: nginx/0.7.63
Cache-Control: private
X-AspNet-Version: 2.0.50727
Set-Cookie: .ASPXANONYMOUS=xTJRqv3wywEkAAAANzg3ZDhjZDgtYjg1Mi00MTc2LWI5YTktYjBiNjgzMzEyMWIxK9hhWfmnVwjy_lIvT6uSgoZim2Q1; domain=rsdn.ru; expires=Sat, 02-Apr-2011 06:17:38 GMT; path=/; HttpOnly
Set-Cookie: ASP.NET_SessionId=1coxtq55iro3q255fr32hfak; path=/; HttpOnly
X-Powered-By: ASP.NET
Вариант 2:
Request
GET / HTTP/1.1
Host: www.rsdn.org
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; ru; rv:1.9.1.16) Gecko/20101130 Firefox/3.5.16
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: ru-ru,ru;q=0.8,en-us;q=0.5,en;q=0.3
Accept-Encoding: gzip,deflate
Accept-Charset: windows-1251,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive
Здравствуйте, st0nx, Вы писали:
S>Здравствуйте, Mazay, Вы писали:
M>>Здравствуйте, Mazay, Вы писали:
M>>>Уже лучше. TCP — это в первую очередь поток, у него нет понятия передаваемого объема. M>>>Покажи HTTP запрос.
M>>И заголовки ответа тоже.
S>Вариант 1:
S>Request
S>
S>GET / HTTP/1.1
S>Host: www.rsdn.org
S>User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; ru; rv:1.9.1.16) Gecko/20101130 Firefox/3.5.16
S>Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
S>Accept-Language: ru-ru,ru;q=0.8,en-us;q=0.5,en;q=0.3
S>Accept-Encoding: gzip,deflate
S>Accept-Charset: windows-1251,utf-8;q=0.7,*;q=0.7 S>Connection: close
Вот здесь соединение должно закрываться само (Connection: close), когда приходят все данные. При этом asio должна вернуть ошибку в error_code то ли при чтении последней порции данных, то ли при попытке чтения на закрытом соединении (то есть после последней порции). Таким образом, если в HttpSendRecv_boost::read_hd пришла ненулевая ошибка, то возвращаем 0 и больше не читаем.
S>Response
S>
S>HTTP/1.1 200 OK
S>Via: 1.1 FT02
S>Connection: close
S>Proxy-Connection: close
S>Content-Length: 1672
S>Date: Thu, 03 Mar 2011 06:17:38 GMT
S>Content-Type: text/html; charset=utf-8
S>Server: nginx/0.7.63
S>Cache-Control: private
S>X-AspNet-Version: 2.0.50727
S>Set-Cookie: .ASPXANONYMOUS=xTJRqv3wywEkAAAANzg3ZDhjZDgtYjg1Mi00MTc2LWI5YTktYjBiNjgzMzEyMWIxK9hhWfmnVwjy_lIvT6uSgoZim2Q1; domain=rsdn.ru; expires=Sat, 02-Apr-2011 06:17:38 GMT; path=/; HttpOnly
S>Set-Cookie: ASP.NET_SessionId=1coxtq55iro3q255fr32hfak; path=/; HttpOnly
S>X-Powered-By: ASP.NET
А здесь соединение не закроется, потому что Connection: keep-alive. Потому нужно смотреть заголовок ответа: Content-Length: 1672. Это размер данных после заголовка. Просто читаешь из сокета, пока не получишь весь объём.
Здравствуйте, Mazay, Вы писали:
M>Здравствуйте, st0nx, Вы писали:
S>>Здравствуйте, Mazay, Вы писали:
M>>>Здравствуйте, Mazay, Вы писали:
M>>>>Уже лучше. TCP — это в первую очередь поток, у него нет понятия передаваемого объема. M>>>>Покажи HTTP запрос.
M>>>И заголовки ответа тоже.
S>>Вариант 1:
S>>Request
S>>
S>>GET / HTTP/1.1
S>>Host: www.rsdn.org
S>>User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; ru; rv:1.9.1.16) Gecko/20101130 Firefox/3.5.16
S>>Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
S>>Accept-Language: ru-ru,ru;q=0.8,en-us;q=0.5,en;q=0.3
S>>Accept-Encoding: gzip,deflate
S>>Accept-Charset: windows-1251,utf-8;q=0.7,*;q=0.7
M>S>Connection: close
M>Вот здесь соединение должно закрываться само (Connection: close), когда приходят все данные. При этом asio должна вернуть ошибку в error_code то ли при чтении последней порции данных, то ли при попытке чтения на закрытом соединении (то есть после последней порции). Таким образом, если в HttpSendRecv_boost::read_hd пришла ненулевая ошибка, то возвращаем 0 и больше не читаем.
S>>Response
S>>
S>>HTTP/1.1 200 OK
S>>Via: 1.1 FT02
S>>Connection: close
S>>Proxy-Connection: close
S>>Content-Length: 1672
S>>Date: Thu, 03 Mar 2011 06:17:38 GMT
S>>Content-Type: text/html; charset=utf-8
S>>Server: nginx/0.7.63
S>>Cache-Control: private
S>>X-AspNet-Version: 2.0.50727
S>>Set-Cookie: .ASPXANONYMOUS=xTJRqv3wywEkAAAANzg3ZDhjZDgtYjg1Mi00MTc2LWI5YTktYjBiNjgzMzEyMWIxK9hhWfmnVwjy_lIvT6uSgoZim2Q1; domain=rsdn.ru; expires=Sat, 02-Apr-2011 06:17:38 GMT; path=/; HttpOnly
S>>Set-Cookie: ASP.NET_SessionId=1coxtq55iro3q255fr32hfak; path=/; HttpOnly
S>>X-Powered-By: ASP.NET