You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于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_; 
};

问题根源与修复方案

问题根源

  1. 单Socket复用冲突:socket_是类成员变量,新连接到来时直接复用该对象,而旧连接的异步操作可能还在使用它,导致资源竞争和内存访问错误。
  2. 异步操作生命周期失效:async_read/async_write依赖的buffer_、request_等成员变量,会被新连接覆盖,导致旧异步操作访问已失效的资源。
  3. 缓冲区错误操作:手动调用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 21:07:12