英文:
Simple Boost TCP Server, example from the book "C++ Crash Course"
问题
以下是您要翻译的内容:
我试图理解在TCP连接情况下使用`std::enable_shared_from_this`的问题,我认为当第一个连接在`serve`函数中被接受时,会创建`Session`类的对象,随后的调用只会创建对同一对象的`shared_ptr`,是吗?如果我理解正确,每次在`serve`中都将套接字移动是否完全正确,我不太确定。下面的示例与书中的原始示例基本相同,只是我添加了`connections`整数:
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 << "当发送结束行时,连接已结束\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 << "已建立连接编号 " << ++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;
}
}
英文:
I'm trying to understand the thing with std::enable_shared_from_this
in case of TCP connections and I see it like when first connection is accepted in the serve
func, object of the class Session
is created and later invocations just create shared_ptr
to the same object isn't it? If I get it well, I'm not sure is it completely correct to move everytime socket in serve
? The below example is like original one from the book besides connections
int I've added:
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;
}
}
答案1
得分: 2
Socket在每次调用serve
时都会被移动,因为它是为新建立的连接而创建的新套接字。请注意,它是按值传递的,除非移动到某个长寿命对象(在本例中是session
),否则在超出作用域后将立即销毁,结束连接。
"Session类的对象创建,后续调用只是创建指向同一对象的shared_ptr,是吗" - 不是的,每次make_shared
调用都会创建一个新的会话对象,每个连接一个。shared_from_this
生成指向当前对象的指针。
英文:
Socket is moved at each invocation of serve
because it is a fresh socket for a newly established connection. Note that it is passed by value and unless moved to some long-living object (session
in this case) it will be immediately destroyed after going out of scope, ending the connection.
"object of the class Session is created and later invocations just create shared_ptr to the same object isn't it" - nope, each make_shared
invocation creates a new session object - one per connection. shared_from_this
spawns pointer to the current object.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论