Simple Boost TCP Server,示例来自书籍《C++ Crash Course》。

huangapple go评论72阅读模式
英文:

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&lt;Session&gt; {
explicit Session(ip::tcp::socket socket) : socket{ std::move(socket) } {}
void read() {
async_read_until(socket, dynamic_buffer(message), &#39;\n&#39;,
[self=shared_from_this()] (boost::system::error_code ec,
std::size_t length) {
if(ec || self-&gt;message == &quot;\n&quot;) {
std::cout&lt;&lt;&quot;Ended connection as endline was sent\n&quot;	;
return;
}
boost::algorithm::to_upper(self-&gt;message);
self-&gt;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-&gt;message.clear();
self-&gt;read();
});
}
private:
ip::tcp::socket socket;
std::string message;
};
void serve(ip::tcp::acceptor&amp; acceptor) {
acceptor.async_accept([&amp;acceptor](boost::system::error_code ec,
ip::tcp::socket socket) {
serve(acceptor);
if (ec) return;
auto session = std::make_shared&lt;Session&gt;(std::move(socket));
std::cout&lt;&lt;&quot;Connection established no &quot;&lt;&lt;++connections&lt;&lt;&quot;\n&quot;;
session-&gt;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&amp; e) {
std::cerr &lt;&lt; e.what() &lt;&lt; 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.

huangapple
  • 本文由 发表于 2023年2月9日 02:20:24
  • 转载请务必保留本文链接:https://go.coder-hub.com/75390136.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定