Увеличить ASIO async_read_some

У меня возникают трудности при реализации простого TCP-сервера. Следующий код взят из примеры boost :: asio, «Http Server 1», чтобы быть точным.

void connection::start() {
socket_.async_read_some(
boost::asio::buffer(buffer_),
boost::bind(
&connection::handle_read, shared_from_this(),
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred
)
);
}
void connection::handle_read(const boost::system::error_code& e, std::size_t bytes_transferred) {
if (!e && bytes_transferred)    {
std::cout << " " << bytes_transferred <<"b" << std::endl;
data_.append(buffer_.data(), buffer_.data()+bytes_transferred);

//(1) what here?
socket_.async_read_some(
boost::asio::buffer(buffer_),
boost::bind(
&connection::handle_read, shared_from_this(),
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred
)
);

}
else// if (e != boost::asio::error::operation_aborted)
{
std::cout << data_ << std::endl;
connection_manager_.stop(shared_from_this());
}
}

В оригинальном коде buffer_ достаточно большой, чтобы сохранить весь запрос. Это не то, что мне нужно. Я изменил размер до 32 байт.

Сервер компилируется и прослушивает порт 80 локального хоста, поэтому я пытаюсь подключиться к нему через свой веб-браузер.

Теперь, если оператор (1) закомментирован, тогда считываются только первые 32 байта запроса, и соединение прерывается. Веб-браузер продолжает ждать ответа, сервер делает .. Я не знаю, что.

Если (1) не закомментировано, тогда весь запрос читается (и добавляется к data_), но это никогда не останавливается — я должен отменить запрос в своем браузере и только после этого else { } часть запуска — я вижу мой запрос на стандартный вывод.

Вопрос 1: Как мне обработать большой запрос?
Вопрос 2: Как я должен кэшировать запрос (в настоящее время я добавляю буфер в строку)?
Вопрос 3: Как я могу сказать, что запрос окончен? В HTTP всегда есть ответ, поэтому мой веб-браузер продолжает его ждать и не закрывает соединение, но как мой сервер может узнать, что запрос завершен (и, возможно, закрыть его или ответить «200 OK»)?

5

Решение

Предположим, браузер отправляет вам 1360 байт данных asio чтобы прочитать некоторые данные в ваш буфер, который, как вы говорите, имеет только 32 байта.
тогда в первый раз, когда вы назовете его, ваш обработчик будет вызван с 32 байтами начала данных. здесь, если вы прокомментируете (1), тогда браузер попытается отправить остальные данные (на самом деле браузер уже отправил их, и он находится в буфере операционной системы, которые ждут, чтобы вы оттуда его посмотрели), и вы, возможно, заблокированы io_service::run за какое-то чудо !!

если вы раскомментируете (1), когда говорите, что ваш цикл запущен, вы читаете первый блок, затем следующий и другой и … до тех пор, пока данные, отправленные браузером, не закончатся, но после этого, когда вы скажете asio чтобы прочитать еще какие-то данные, он будет ждать больше данных, которые никогда не поступят из браузера (так как браузер уже отправил свою информацию и ожидает вашего ответа), и когда вы отмените запрос из браузера, он закроет свой сокет и затем ваш Обработчик будет вызван с ошибкой, которая говорит, что я не могу прочитать больше данных, так как соединение закрыто. !!

но то, что вы должны сделать здесь, чтобы это сработало: вы должны научиться HTTP отформатируйте и, таким образом, узнайте, какие данные отправил вам ваш браузер, и дайте на них хороший ответ, после чего будет продолжено ваше общение с клиентом. в этом случае конец буфера \r\n\r\n и когда вы видите это, вы не должны больше читать данные, вы должны обработать то, что прочитали до сих пор, а затем отправить ответ в браузер.

9

Другие решения

Других решений пока нет …