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

《C++ Crash Course》Boost TCP Server:std::enable_shared_from_this与socket移动疑问

关于TCP连接场景下std::enable_shared_from_this与Socket移动的疑问解答

问题1:Session对象的创建逻辑

你的理解错误。每次serve处理新TCP连接时,都会创建一个全新的Session实例,并用std::make_shared生成指向该新实例的shared_ptr。std::enable_shared_from_this的作用是让Session内部可以生成指向自身的shared_ptr(即shared_from_this()),用于在异步操作的回调中维持对象生命周期,而非复用同一个Session对象。每个TCP连接对应独立的Session,以此为不同连接维护专属的socket和消息缓冲区状态。

问题2:Socket的移动操作

每次在serve中移动socket是完全正确的。ip::tcp::socket支持移动语义,通过std::move将socket所有权转移给Session对象,既避免了不必要的资源拷贝,也符合Boost.Asio的设计理念——socket所有权应由负责处理该连接的会话对象持有,直到连接关闭后由Session析构函数自动清理socket资源。

示例代码

using namespace boost::asio;
int connections{};

struct Session : std::enable_shared_from_this<Session> {
    explicit Session(ip::tcp::socket socket) : socket{ std::move(socket) } {}
    void read() {
        async_read_until(socket, dynamic_buffer(message), '\n',
        [self=shared_from_this()] (boost::system::error_code ec,
        std::size_t length) {
            if(ec || self->message == "\n") {
            std::cout<<"Ended connection as endline was sent\n" ;
            return;
            }
            boost::algorithm::to_upper(self->message);
            self->write();
        });
    }
    void write() {
        async_write(socket, buffer(message),
        [self=shared_from_this()] (boost::system::error_code ec,
        std::size_t length) {
            if(ec) return;
            self->message.clear();
            self->read();
        });
    }
    private:
    ip::tcp::socket socket;
    std::string message;
};

void serve(ip::tcp::acceptor& acceptor) {
    acceptor.async_accept([&acceptor](boost::system::error_code ec,
    ip::tcp::socket socket) {
        serve(acceptor);
        if (ec) return;
        auto session = std::make_shared<Session>(std::move(socket));
        std::cout<<"Connection established no "<<++connections<<"\n";
        session->read();
    });
}

int main(){
    try{
        io_context io_context;
        ip::tcp::acceptor acceptor{ io_context,
        ip::tcp::endpoint(ip::tcp::v4(), 1895)};
        
        serve(acceptor);
        io_context.run();
    } catch (std::exception& e) {
        std::cerr << e.what() << std::endl;
    }
}

内容的提问来源于stack exchange,提问作者Jacob

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 03:20:52