Bezdepbonusu7Программирование: статьи и ответы

Вопрос

Ускорить ASIO async_read_some

Автор вопроса: QueequegОтветов: 1

У меня возникли трудности с реализацией простого 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")?

c++networkingboostboost-asio

Ответы

Ответ 1 · рейтинг 9 · BigBoss

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

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

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

Перевод вопроса и ответов сообщества Stack Overflow, лицензия CC BY-SA. Оригинал на Stack Overflow.

Похожие материалы