反复的std ::上的boost :: ASIO Socket对象在C ++ 11移动 [英] Repeated std::move on an boost::asio socket object in C++11
问题描述
我使用boost ::与C ++ 11的特性以及ASIO探索。特别是,我专注于所谓的async_tcp_echo_server.cpp为例,设在这里(code也是在我的问题的最后面):
<一个href=\"http://www.boost.org/doc/libs/1_54_0/doc/html/boost_asio/example/cpp11/echo/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
我的问题涉及到 TCP ::插座
成员插座_
的的服务器
类。在 do_accept()
的服务器
类的方法,插座_
传递给 async_accept()
。 (据ASIO文档, async_accept()
要求,作为第一个参数,在插座
来接受连接成)。到目前为止,一切都很好。
下一个参数,回调的异步接收操作,是一个lambda函数。拉姆达的身体构造一个新的会议
的对象,它的构造也需要同样的插座
。有趣的是,插座
对象不能被复制;因此在本例中,插座_
对象,这是服务器
对象的成员,使用<$ C传递$ C>的std ::移动()。
据我所知,有且仅有插座_
对象(这是的永久成员服务器
对象)被搬到会议
对象。精 - 插座
对象是不可复制的,但移动 - 皆大欢喜
但在下次调用 async_accept会发生什么()
?是同一个插座_
(服务器的成员
),这是previously移动,再次通过呢?当我们动的一员,是什么留下什么呢?有无限的插座的神奇喷泉
对象?
或者是一些真正低于明显的发生在这里?当插座
移动到会议
,是对内容对象(留守从/移动插座_
)的换的与新<$ C $的内容C>会议对象自己还未构建服务器
成员插座_
会员?难道我连说的吗?
摘要
code如下。程序流程相当简单。 的main()
构建一个服务器
对象。在服务器
使得重复 async_accept电话()
。每个 async_accept()
回调创建一个新的会议
对象,每一个(新的?)插槽
。在哪里所有的新鲜插座
对象来自,如果他们只是(反复)来自同一插座_ $ C $感动 C>成员(单个)
服务器
?
的#include&LT; cstdlib&GT;
#包括LT&;&iostream的GT;
#包括LT&;内存和GT;
#包括LT&;实用&GT;
#包括LT&;升压/ asio.hpp&GT;使用boost ::支持ASIO ::知识产权:: TCP;堂课
:公众的std :: enable_shared_from_this&LT;会议&GT;
{
上市:
会话(TCP ::插座插座)
:socket_(性病::移动(插座))
{} 无效的start(){
do_read();
}私人的:
无效do_read(){
自动自我(shared_from_this());
socket_.async_read_some(
提高:: ASIO ::缓冲区(data_中的数据,MAX_LENGTH)
[本,个体经营](升压::系统::错误_ code EC,性病::为size_t长度)
{
如果(!EC){
do_write(长);
}
}
);
} 无效do_write(的std ::为size_t长度){
自动自我(shared_from_this());
提高:: ASIO :: async_write(
插座_,
提高:: ASIO ::缓冲区(data_中的数据,长度)
[本,个体经营](升压::系统::错误_ code EC,性病::为size_t / *长* /)
{
如果(!EC){
do_read();
}
}
);
} TCP ::插座socket_;
枚举{MAX_LENGTH = 1024};
烧焦data_中的数据[MAX_LENGTH]
};
级服务器{
上市:
服务器(提高:: ASIO :: io_service对象和放大器; io_service对象,短端口)
:acceptor_(io_service对象,TCP ::端点(TCP :: V4(),口))
,socket_(io_service对象)
{
do_accept();
}私人的:
无效do_accept(){
acceptor_.async_accept(
插座_,
[这](升压::系统::错误_ code EC)
{
如果(!EC){
的std :: make_shared&LT;会议&GT;(的std ::移动(socket_)) - &GT;启动(); //这是一个socket_ * *互换?
} do_accept();
}
);
} TCP ::受acceptor_;
TCP ::插座socket_;
};
INT主(INT ARGC,CHAR *的argv []){
尝试{
如果(的argc!= 2){
的std :: CERR&LT;&LT; 用法:async_tcp_echo_server&LT;港口&GT; \\ N的;
返回1;
} 提高:: ASIO :: io_service对象io_service对象; 服务器S(io_service对象,性病::与atoi(ARGV [1])); io_service.run(); }赶上(的std ::例外急症){
的std :: CERR&LT;&LT; 例外:&LT;&LT; e.what()&所述;&下; \\ n;
} 返回0;
}
作为<一个记录href=\"http://www.boost.org/doc/libs/1_54_0/doc/html/boost_asio/reference/basic_stream_socket/basic_stream_socket/overload5.html\"><$c$c>tcp::socket$c$c>参考:
继移动,移动的,从对象处于相同的状态,如果
使用basic_stream_socket(io_service对象和放大器;)构成。构造
块引用>以上意味着你可以
移动
从服务器的原始
到插座
对象会议
多次,因为你需要。I am exploring using boost::asio along with C++11 features. In particular, I am focusing on an example called "async_tcp_echo_server.cpp", located here (code is also shown at the end of my question):
My question involves the
tcp::socket
membersocket_
of theserver
class. In thedo_accept()
method of theserver
class,socket_
is passed toasync_accept()
. (According to the asio documentation,async_accept()
requires, as its first parameter, thesocket
to accept the connection into.) So far, so good.The next parameter, the callback for the asynchronous accept operation, is a lambda function. The body of the lambda constructs a new
session
object, whose constructor also needs the samesocket
. Interestingly,socket
objects cannot be copied; so in the example, thesocket_
object, which is a member of theserver
object, is passed usingstd::move()
.I understand that the "one and only"
socket_
object (which is a "permanent" member of theserver
object) is "moved" into thesession
object. Fine --socket
object is not copied, but moved -- everybody's happy.But what happens on the next call to
async_accept()
? Is the samesocket_
(member ofserver
), that was previously moved, passed in again? When we "move" a member, what is left behind? Is there a magical fountain of unlimitedsocket
objects?Or is something really less-than-obvious happening here? When the
socket
is moved into thesession
, is the contents of the "left behind/moved from" object (socket_
member ofserver
) swapped with the contents of the "new"session
object's own "not-yet-constructed"socket_
member? Am I even making sense?Summary
Code is below. Program flow is fairly simple.
main()
constructs a singleserver
object. Theserver
makes repeated calls toasync_accept()
. Eachasync_accept()
callback creates a newsession
object, each constructed with a (fresh?)socket
. Where do all the "fresh"socket
objects come from, if they are simply (repeatedly) "moved" from the samesocket_
member in the (single)server
?#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; }
解决方案As documented in
tcp::socket
reference:Following the move, the moved-from object is in the same state as if constructed using the basic_stream_socket(io_service&) constructor.
The above means that you can
move
the originalsocket
object fromserver
tosession
as many times as you need.这篇关于反复的std ::上的boost :: ASIO Socket对象在C ++ 11移动的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!