首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >在C++11中的boost::asio套接字对象上重复std::move

在C++11中的boost::asio套接字对象上重复std::move
EN

Stack Overflow用户
提问于 2013-07-18 14:10:45
回答 1查看 4.6K关注 0票数 24

我正在探索结合使用boost::asio和C++11特性。特别是,我将重点介绍一个名为"async_tcp_echo_server.cpp“的示例,位于此处(代码也显示在我的问题的末尾):

http://www.boost.org/doc/libs/1_54_0/doc/html/boost_asio/example/cpp11/echo/async_tcp_echo_server.cpp

我的问题涉及到server类的tcp::socket成员socket_。在server类的do_accept()方法中,socket_被传递给async_accept()。(根据asio文档,async_accept()需要将接受连接的socket作为其第一个参数。)到现在为止还好。

下一个参数是异步接受操作的回调,它是一个lambda函数。lambda的主体构造了一个新的session对象,该对象的构造函数也需要相同的socket。有趣的是,socket对象不能被复制;因此在本例中,作为server对象成员的socket_对象是使用std::move()传递的。

我知道“唯一的”socket_对象(它是server对象的“永久”成员)被“移动”到session对象中。很好-- socket对象没有被复制,而是被移动了--大家都满意了。

但是下一次调用async_accept()时会发生什么呢?之前移动的同一个socket_ (server的成员)是否再次传入?当我们“移动”一个成员时,留下了什么?是否有无限socket对象的神奇喷泉?

或者这里真的发生了一些不那么明显的事情?当socket移动到session中时,“留下/移动自”对象(serversocket_成员)的内容是否与“新的”session对象自己的“尚未构造”的socket_成员的内容交换?我说的有道理吗?

摘要

代码如下。程序流程相当简单。main()构造单个server对象。server反复调用async_accept()。每个async_accept()回调都会创建一个新的session对象,每个对象都用一个(fresh?) socket构造。如果只是(重复地)从(单个) socket中的同一个socket_成员“移动”所有“新的”server对象,那么它们从哪里来呢

代码语言:javascript
复制
#include <cstdlib>
#include <iostream>
#include <memory>
#include <utility>
#include <boost/asio.hpp>

using boost::asio::ip::tcp;

class session
: public std::enable_shared_from_this<session>
{
public:
    session( tcp::socket socket )
    : socket_( std::move( socket ) )
    {}

    void start() {
        do_read();
    }

private:
    void do_read() {
        auto self( shared_from_this() );
        socket_.async_read_some(
            boost::asio::buffer( data_, max_length ),
            [this, self]( boost::system::error_code ec, std::size_t length )
            {
                if( !ec ) {
                    do_write( length );
                }
            }
        );
    }

    void do_write( std::size_t length ) {
        auto self( shared_from_this() );
        boost::asio::async_write(
            socket_,
            boost::asio::buffer( data_, length ),
            [this, self]( boost::system::error_code ec, std::size_t /*length*/ )
            {
                if( !ec ) {
                    do_read();
                }
            }
        );
    }

    tcp::socket socket_;
    enum { max_length = 1024 };
    char data_[max_length];
};


class server {
public:
    server( boost::asio::io_service& io_service, short port )
    : acceptor_( io_service, tcp::endpoint( tcp::v4(), port ) )
    , socket_( io_service )
    {
        do_accept();
    }

private:
    void do_accept() {
        acceptor_.async_accept(
            socket_,
            [this]( boost::system::error_code ec )
            {
               if( !ec ) {
                   std::make_shared<session>( std::move( socket_ ) )->start();  // is this a *swap* of socket_ ???
               }

               do_accept();
            }
        );
    }

    tcp::acceptor acceptor_;
    tcp::socket socket_;
};


int main( int argc, char* argv[] ) {
    try {
        if( argc != 2 ) {
            std::cerr << "Usage: async_tcp_echo_server <port>\n";
            return 1;
        }

        boost::asio::io_service io_service;

        server s( io_service, std::atoi( argv[1] ) );

        io_service.run();

    } catch( std::exception& e ) {
        std::cerr << "Exception: " << e.what() << "\n";
    }

    return 0;
} 
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-05-14 14:57:22

移动语义可以被认为是传递资源的所有权。资源获取即实例化(RAII)是在对象构造时分配资源所有权并在销毁时释放这些资源的概念。移动语义允许在构造和销毁之外的其他时间转移资源的所有权。

在这种情况下,对象(server::socket_)是从server::acceptor_转移操作系统套接字资源所有权的接收方。这种传输发生在async_accept()返回后的某个时刻,也就是客户端连接时。将新连接的套接字资源移到socket_中,并调用回调lambda函数。在lambda过程中,套接字资源被转移到session::socket_中。Server::socket_拥有该资源的时间只有几分之一微秒。

移动语义允许RAII类以不拥有任何资源的模糊状态存在。想一想调用release之后的unique_ptr (它指的是没有内存)。搬出后的server::socket_仍然有空间容纳资源,但目前它什么都不拥有。

lambda函数做的最后一件事是调用do_accept,后者再次调用async_accept()。传入一个对socket_的引用。当另一个客户端在未来的某个时候连接时,async_accept()会将一个新连接的OS套接字的所有权转移到那里。

票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17715794

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档