提升 Asio 损坏的缓冲区

Boost Asio corrupted buffer

提问人:MicMaclaynd 提问时间:8/29/2023 更新时间:8/30/2023 访问量:31

问:

我使用读取功能向服务器发送请求,但是在接收数据时,缓冲区中出现了第三方数据,这仅出现在服务器上,但是在家用PC上一切正常,这是发送请求的代码。

std::string send(std::string _hostName, std::string _rawRequest, std::string _ipAddress = "default") {
    boost::system::error_code ec;
    boost::asio::ip::tcp::resolver resolver(_IoContext);
    boost::asio::ssl::context ssl_context = boost::asio::ssl::context(boost::asio::ssl::context::sslv23_client);
    boost::asio::ssl::stream<boost::asio::ip::tcp::socket> socket(_IoContext, ssl_context);

    try {
        boost::asio::ip::tcp::resolver::results_type endpoints = resolver.resolve(_hostName, "https", ec);
        if (ec) throw std::exception(ec.what().c_str());

        socket.lowest_layer().open(boost::asio::ip::tcp::v4(), ec);
        if (ec) throw std::exception(ec.what().c_str());

        if (_ipAddress != "default") {
            socket.lowest_layer().bind(boost::asio::ip::tcp::endpoint(boost::asio::ip::address_v4::from_string(_ipAddress), 0), ec);
            if (ec) throw std::exception(ec.what().c_str());
        }

        socket.lowest_layer().connect(*endpoints, ec);
        if (ec) throw std::exception(ec.what().c_str());

        socket.handshake(boost::asio::ssl::stream_base::client, ec);
        if (ec) throw std::exception(ec.what().c_str());

        boost::asio::streambuf buffer;
        std::ostream buffer_stream(&buffer);
        buffer_stream << _rawRequest;
        boost::asio::write(socket, buffer, ec);
            if (ec) throw std::exception(ec.what().c_str());

        boost::asio::streambuf response;
        boost::asio::read(socket, response, boost::asio::transfer_all(), ec);

        boost::asio::streambuf::const_buffers_type response_buffer = response.data();
        std::string response_str = boost::asio::buffer_cast<const char*>(response.data());

        socket.shutdown(ec);
        socket.lowest_layer().shutdown(boost::asio::ip::tcp::socket::shutdown_both, ec);
        socket.lowest_layer().cancel(ec);
        socket.lowest_layer().close();

        return response_str;
    } catch (std::exception& e) {
        throw std::exception(std::format("{} from {}", e.what(), _ipAddress).c_str());
    }
}

我尝试进行不同的缓冲区转换,并稍微更改了读取函数中的参数,但没有任何帮助。

C++ HTTP Boost ASIO

评论

0赞 Jakob Stark 8/29/2023
转换为仅适用于以 null 结尾的字符串。您应该使用构造函数,它允许您指定缓冲区的长度。或者,您可以创建一个 on 并使用运算符,如下所示const char*std::stringstd::stringsstd::istreamstreambuf>>
0赞 MicMaclaynd 8/30/2023
感谢您的评论,但问题原来是 ,这导致出现干扰 json 解析的块大小。Transfer-Encoding: chunked

答:

0赞 MicMaclaynd 8/30/2023 #1

问题不在于代码,而在于 http 标头,因此 http 正文中出现了块大小,这在解析 json 时导致了问题。Transfer-Encoding: chunked

评论

1赞 sehe 8/31/2023
请注意,Boost Beast 支持 HTTP(包括分块编码等)