async_read_until在分隔符读取之前完成

时间:2013-05-20 15:07:32

标签: c++ boost network-programming boost-asio

我在使用async_read_until时遇到问题。我最初使用的是async_receive,但是我服务器的响应增长到不止一个数据包,我遇到了一个问题,即async_receive会在收到第一个数据包后停止读取。然后我查看了async_read_until并尝试读取,直到达到分隔符。然而,这似乎是一个问题,每当我使用async_read_until时,我的streambuf对象似乎只会到第一个空格。这是我正在使用的代码:

bool request_handler::get_recommendation(std::string& content, std::string &returnJson)
{
    //Connect to recommendation engine
    boost::asio::io_service io_service;
    boost::asio::ip::tcp::socket socket(io_service);
    boost::asio::ip::tcp::resolver resolver(io_service);
    boost::asio::ip::tcp::resolver::query query(Settings::get_recommendation_ip(), Settings::get_recommendation_port(), boost::asio::ip::resolver_query_base::numeric_service);
    boost::asio::ip::tcp::resolver::iterator iterator = resolver.resolve(query);
    boost::asio::ip::tcp::endpoint endpoint = *iterator;
    boost::system::error_code ec;
    socket.connect(endpoint, ec);
    if(ec)
    {
        Log::error("Couldn't connect: " + ec.message());
        return false;
    }

    //Create post Message
    std::string request_information = "POST / HTTP/1.1\r\n";
    request_information += "Host: " + Settings::get_recommendation_ip() + "\r\n";
    request_information += "Accept: */*\r\n";
    request_information += "Content-Type:text/plain\r\n";
    request_information += "Content-Length:" + boost::lexical_cast<std::string>(content.size()) + "\r\n";
    request_information += "Connection: close\r\n\r\n";
    request_information += content;

    try
    {        
        boost::shared_ptr<bool> timer1_result(new bool(false));
        boost::shared_ptr<bool> timer2_result(new bool(false));
        boost::shared_ptr<bool> write_result(new bool(false));
        boost::shared_ptr<bool> read_result(new bool(false));

//        boost::array<char,8192> buf;
        boost::asio::streambuf buf;
//        buf.assign(0);

        boost::asio::deadline_timer dt(io_service);
        //Create write timer
        dt.expires_from_now(boost::posix_time::milliseconds(Settings::get_write_timeout()));
        dt.async_wait(boost::bind(&request_handler::set_result, this, timer1_result, _1));
        //Call async write
        boost::asio::async_write(socket, boost::asio::buffer(request_information, request_information.size()), boost::bind(&request_handler::set_result, this, write_result, _1));
        io_service.reset();

        //Run until either the timer finishes or the write completes
        while(io_service.run_one())
        {
            //Write completes
            if(*write_result)
            {
                //Stop the timer
                dt.cancel();
                break;
            }
            //Timer completes
            else if(*timer1_result)
            {
                //Stop the write
                socket.cancel();
                return false;
            }
        }

        boost::asio::deadline_timer dt2(io_service);
        //Create read timer
        dt2.expires_from_now(boost::posix_time::milliseconds(Settings::get_read_timeout()));
        dt2.async_wait(boost::bind(&request_handler::set_result, this, timer2_result, _1));
        //Call async_receive
//        socket.async_receive(boost::asio::buffer(buf), boost::bind(&request_handler::set_result, this, read_result, _1));
        boost::asio::async_read_until(socket, buf, "]", boost::bind(&request_handler::set_result, this, read_result, _1));

        io_service.reset();
        //Run until either the timer finishes or the receive completes
        while(io_service.run_one())
        {
            //Receive completes
            if(*read_result)
            {
                //Stop timer
//                dt2.cancel();
//                break;
            }
            else if(*timer2_result)
            {
                //Stop the write
                socket.cancel();
                break;
            }
        }

        //Put result in return string
//        returnJson = buf.data();
        std::istream is(&buf);
        is >> returnJson;
        std::cout << "***" << returnJson << std::endl;
        return true;
    }catch(std::exception& e)
    {
        return false;
    }

}

void request_handler::set_result(boost::shared_ptr<bool> a, boost::system::error_code ec)
{
    std::cout << ec.message() << std::endl;
    *a = true;   
}

我认为问题可能是我需要更多调用read_until并且整个数据包没有被立即读入,但我无法获得比#34; HTTP / 1.1&更多的数据#34;我读到的关于streambuf的回复。有什么问题可能是什么?

1 个答案:

答案 0 :(得分:3)

这一行:

    is >> returnJson;

只能通过空格读取。请参阅std::basic_string::operator>>的规范。要获取整个streambuf内容,请尝试Copy a streambuf's contents to a string

相关问题