基于Boost Beast的API服务器首次连接后崩溃(错误码-1073741819)求助
问题描述
我正在开发一个可接收其他应用请求的REST API服务器,首次建立连接后服务器就崩溃,抛出错误码-1073741819。调试发现错误源于buffer_的未处理异常:发生未处理异常:读取访问权限冲突,地址为0xffffffffffffffffff,不知道该怎么解决。
相关代码
Server.cpp
#include "Server.h" using namespace boost::asio; namespace beast = boost::beast; namespace http = beast::http; using tcp = boost::asio::ip::tcp; Server::Server(boost::asio::io_service& io_service, int port) : acceptor_(io_service, boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), port)), socket_(io_service) { StartAccept(); } void Server::StartAccept() { acceptor_.async_accept(socket_, [this](boost::system::error_code ec) { if (!ec) { std::cout << "Client connected" << std::endl; ReadRequest(); } else { std::cerr << "Client error: " << ec.message() << std::endl; } }); } void Server::ReadRequest() { buffer_.consume(buffer_.size()); buffer_.prepare(1024); beast::http::async_read(socket_, buffer_, request_, [this](boost::system::error_code ec, size_t bytes_transferred) { if (!ec) { ProcessRequest(); } else { std::cerr << "Error ReadRequest: " << ec.message() << std::endl; } }); } void Server::ProcessRequest(){ if (request_.method() == http::verb::get) { http::response<http::string_body> response(http::status::ok, request_.version()); response.set(http::field::server, "Boost Beast Server"); response.set(http::field::content_type, "text/plain"); response.keep_alive(request_.keep_alive()); response.body() = "Hello, World"; response.prepare_payload(); WriteResponse(response); } else { http::response<http::string_body> response(http::status::bad_request, request_.version()); response.set(http::field::server, "Boost Beast Server"); response.set(http::field::content_type, "text/plain"); response.keep_alive(request_.keep_alive()); response.body() = "Invalide request!"; response.prepare_payload(); WriteResponse(response); } } void Server::WriteResponse(boost::beast::http::response<boost::beast::http::string_body>& response_){ http::async_write(socket_, response_, [this](boost::system::error_code ec, size_t byte) { if (ec) { std::cerr << "Error WriteResponse: " << ec.message() << std::endl; } StartAccept(); }); }
Server.h
#include <iostream> #include <boost/asio.hpp> #include <boost/beast.hpp> #include <string> class Server { public: Server(boost::asio::io_service& io_service, int port); private: void StartAccept(); void ReadRequest(); void ProcessRequest(); void WriteResponse(boost::beast::http::response <boost::beast::http::string_body>& response_); boost::asio::ip::tcp::acceptor acceptor_; boost::asio::ip::tcp::socket socket_; boost::beast::flat_buffer buffer_; boost::beast::http::request<boost::beast::http::string_body> request_; };
问题根源与修复方案
问题根源
- 单Socket复用冲突:
socket_是类成员变量,新连接到来时直接复用该对象,而旧连接的异步操作可能还在使用它,导致资源竞争和内存访问错误。 - 异步操作生命周期失效:
async_read/async_write依赖的buffer_、request_等成员变量,会被新连接覆盖,导致旧异步操作访问已失效的资源。 - 缓冲区错误操作:手动调用
buffer_.prepare(1024)多余且干扰http::async_read的内部缓冲区管理逻辑,引发状态混乱。
修复方案
为每个连接创建独立的处理对象,用std::shared_ptr管理生命周期,确保异步操作完成前资源有效。
修复后的Server.cpp
#include "Server.h" using namespace boost::asio; namespace beast = boost::beast; namespace http = beast::http; using tcp = boost::asio::ip::tcp; Server::Server(boost::asio::io_service& io_service, int port) : acceptor_(io_service, tcp::endpoint(tcp::v4(), port)) { StartAccept(); } void Server::StartAccept() { auto socket = std::make_shared<tcp::socket>(acceptor_.get_io_service()); acceptor_.async_accept(*socket, [this, socket](boost::system::error_code ec) { if (!ec) { std::cout << "Client connected" << std::endl; std::make_shared<Session>(socket)->Start(); } else { std::cerr << "Client error: " << ec.message() << std::endl; } StartAccept(); // 持续监听新连接 }); } // Session类实现 Session::Session(std::shared_ptr<tcp::socket> socket) : socket_(socket) {} void Session::Start() { ReadRequest(); } void Session::ReadRequest() { auto self(shared_from_this()); http::async_read(*socket_, buffer_, request_, [this, self](boost::system::error_code ec, size_t bytes_transferred) { if (!ec) { ProcessRequest(); } else { std::cerr << "Error ReadRequest: " << ec.message() << std::endl; } }); } void Session::ProcessRequest() { http::response<http::string_body> response; if (request_.method() == http::verb::get) { response = http::response<http::string_body>(http::status::ok, request_.version()); response.set(http::field::server, "Boost Beast Server"); response.set(http::field::content_type, "text/plain"); response.keep_alive(request_.keep_alive()); response.body() = "Hello, World"; } else { response = http::response<http::string_body>(http::status::bad_request, request_.version()); response.set(http::field::server, "Boost Beast Server"); response.set(http::field::content_type, "text/plain"); response.keep_alive(request_.keep_alive()); response.body() = "Invalid request!"; } response.prepare_payload(); WriteResponse(response); } void Session::WriteResponse(http::response<http::string_body> response) { auto self(shared_from_this()); http::async_write(*socket_, response, [this, self](boost::system::error_code ec, size_t bytes_written) { if (ec) { std::cerr << "Error WriteResponse: " << ec.message() << std::endl; } // 发送完成后关闭socket(若需keep-alive可改为继续读取) socket_->shutdown(tcp::socket::shutdown_send, ec); }); }
修复后的Server.h
#include <iostream> #include <boost/asio.hpp> #include <boost/beast.hpp> #include <string> #include <memory> namespace beast = boost::beast; namespace http = beast::http; using tcp = boost::asio::ip::tcp; class Session : public std::enable_shared_from_this<Session> { public: Session(std::shared_ptr<tcp::socket> socket) : socket_(socket) {} void Start(); private: void ReadRequest(); void ProcessRequest(); void WriteResponse(http::response<http::string_body> response); std::shared_ptr<tcp::socket> socket_; beast::flat_buffer buffer_; http::request<http::string_body> request_; }; class Server { public: Server(boost::asio::io_service& io_service, int port); private: void StartAccept(); tcp::acceptor acceptor_; };
关键修复点说明
- Session类隔离连接:每个连接对应独立的Session对象,用
std::shared_ptr确保异步操作期间资源不被销毁。 - 资源独立化:每个Session拥有专属的
socket_、buffer_和request_,避免复用冲突。 - 移除无效缓冲区操作:删除
buffer_.prepare(1024),交由http::async_read自动管理缓冲区。 - 规范连接生命周期:新连接创建新socket,响应完成后关闭socket,避免资源泄漏。
内容的提问来源于stack exchange,提问作者zxctatar
相关产品推荐
相关产品推荐

