std::optional<boost::asio::ip::tcp::socket> 使用 socket.emplace() 进行初始化
std::optional<boost::asio::ip::tcp::socket> initializing using socket.emplace()
我有以下示例代码,它使用 boost::asio
实现异步服务器
我正在尝试理解代码。我对代码的疑问如下
在class server
中的函数async_accept()
中,第一条语句是
socket.emplace(io_context)
据我了解,这一行调用套接字构造函数,创建一个套接字。
然后将此套接字传递给会话 usign std::move()
.
当再次调用async_accept()时,在函数的最后一行,创建了一个新的套接字。
我的理解正确吗?我错过了什么吗?
#include <iostream>
#include <optional>
#include <boost/asio.hpp>
class session : public std::enable_shared_from_this<session>
{
public:
session(boost::asio::ip::tcp::socket&& socket)
: socket(std::move(socket))
{
}
void start()
{
boost::asio::async_read_until(socket, streambuf, '\n', [self = shared_from_this()] (boost::system::error_code error, std::size_t bytes_transferred)
{
std::cout << std::istream(&self->streambuf).rdbuf();
});
}
private:
boost::asio::ip::tcp::socket socket;
boost::asio::streambuf streambuf;
};
class server
{
public:
server(boost::asio::io_context& io_context, std::uint16_t port)
: io_context(io_context)
, acceptor (io_context, boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), port))
{
}
void async_accept()
{
socket.emplace(io_context);
acceptor.async_accept(*socket, [&] (boost::system::error_code error)
{
std::make_shared<session>(std::move(*socket))->start();
async_accept();
});
}
private:
boost::asio::io_context& io_context;
boost::asio::ip::tcp::acceptor acceptor;
std::optional<boost::asio::ip::tcp::socket> socket;
};
int main()
{
boost::asio::io_context io_context;
server srv(io_context, 15001);
srv.async_accept();
io_context.run();
return 0;
}
您对可选的理解是正确的。
acceptor.async_accept(*socket, [&] (boost::system::error_code error)
{
std::make_shared<session>(std::move(*socket))->start();
async_accept();
});
等待连接,如果建立了连接,则执行括号内的代码,创建一个会话对象,该对象具有一个套接字作为成员,然后是“server::async_accept();”被递归调用,因此我们可以接受另一个连接。
顺便说一句:我没有看到使用可选的原因。
我建议删除成员变量
std::optional<boost::asio::ip::tcp::socket> socket;
并将 Server::async_accept() 替换为
void
async_accept ()
{
auto socket = std::make_shared<boost::asio::ip::tcp::socket> (io_context);
acceptor.async_accept (*socket, [&, socket] (boost::system::error_code error) {
std::make_shared<session> (std::move (*socket))->start ();
async_accept ();
});
}
完整且经过测试的示例:
#include <boost/asio.hpp>
#include <iostream>
#include <memory>
#include <optional>
class session : public std::enable_shared_from_this<session>
{
public:
session (boost::asio::ip::tcp::socket &&socket) : socket (std::move (socket)) {}
void
start ()
{
boost::asio::async_read_until (socket, streambuf, '\n', [self = shared_from_this ()] (boost::system::error_code error, std::size_t bytes_transferred) { std::cout << std::istream (&self->streambuf).rdbuf (); });
}
private:
boost::asio::ip::tcp::socket socket;
boost::asio::streambuf streambuf;
};
class server
{
public:
server (boost::asio::io_context &io_context, std::uint16_t port) : io_context (io_context), acceptor (io_context, boost::asio::ip::tcp::endpoint (boost::asio::ip::tcp::v4 (), port)) {}
void
async_accept ()
{
auto socket = std::make_shared<boost::asio::ip::tcp::socket> (io_context);
acceptor.async_accept (*socket, [&, socket] (boost::system::error_code error) {
std::make_shared<session> (std::move (*socket))->start ();
async_accept ();
});
}
private:
boost::asio::io_context &io_context;
boost::asio::ip::tcp::acceptor acceptor;
};
int
main ()
{
boost::asio::io_context io_context;
server srv (io_context, 15001);
srv.async_accept ();
io_context.run ();
return 0;
}
您可以在浏览器中通过 运行 "localhost:15001" 进行测试。检查它打印的服务器输出:
GET / HTTP/1.1
Host: localhost:15001
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:90.0) Gecko/20100101 Firefox/90.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Connection: keep-alive
Upgrade-Insecure-Requests: 1
Sec-Fetch-Dest: document
Sec-Fetch-Mode: navigate
Sec-Fetch-Site: none
Sec-Fetch-User: ?1
编辑:修复 liv2hak
评论中报告的错误
我有以下示例代码,它使用 boost::asio
我正在尝试理解代码。我对代码的疑问如下
在class server
中的函数async_accept()
中,第一条语句是
socket.emplace(io_context)
据我了解,这一行调用套接字构造函数,创建一个套接字。
然后将此套接字传递给会话 usign std::move()
.
当再次调用async_accept()时,在函数的最后一行,创建了一个新的套接字。 我的理解正确吗?我错过了什么吗?
#include <iostream>
#include <optional>
#include <boost/asio.hpp>
class session : public std::enable_shared_from_this<session>
{
public:
session(boost::asio::ip::tcp::socket&& socket)
: socket(std::move(socket))
{
}
void start()
{
boost::asio::async_read_until(socket, streambuf, '\n', [self = shared_from_this()] (boost::system::error_code error, std::size_t bytes_transferred)
{
std::cout << std::istream(&self->streambuf).rdbuf();
});
}
private:
boost::asio::ip::tcp::socket socket;
boost::asio::streambuf streambuf;
};
class server
{
public:
server(boost::asio::io_context& io_context, std::uint16_t port)
: io_context(io_context)
, acceptor (io_context, boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), port))
{
}
void async_accept()
{
socket.emplace(io_context);
acceptor.async_accept(*socket, [&] (boost::system::error_code error)
{
std::make_shared<session>(std::move(*socket))->start();
async_accept();
});
}
private:
boost::asio::io_context& io_context;
boost::asio::ip::tcp::acceptor acceptor;
std::optional<boost::asio::ip::tcp::socket> socket;
};
int main()
{
boost::asio::io_context io_context;
server srv(io_context, 15001);
srv.async_accept();
io_context.run();
return 0;
}
您对可选的理解是正确的。
acceptor.async_accept(*socket, [&] (boost::system::error_code error)
{
std::make_shared<session>(std::move(*socket))->start();
async_accept();
});
等待连接,如果建立了连接,则执行括号内的代码,创建一个会话对象,该对象具有一个套接字作为成员,然后是“server::async_accept();”被递归调用,因此我们可以接受另一个连接。
顺便说一句:我没有看到使用可选的原因。
我建议删除成员变量
std::optional<boost::asio::ip::tcp::socket> socket;
并将 Server::async_accept() 替换为
void
async_accept ()
{
auto socket = std::make_shared<boost::asio::ip::tcp::socket> (io_context);
acceptor.async_accept (*socket, [&, socket] (boost::system::error_code error) {
std::make_shared<session> (std::move (*socket))->start ();
async_accept ();
});
}
完整且经过测试的示例:
#include <boost/asio.hpp>
#include <iostream>
#include <memory>
#include <optional>
class session : public std::enable_shared_from_this<session>
{
public:
session (boost::asio::ip::tcp::socket &&socket) : socket (std::move (socket)) {}
void
start ()
{
boost::asio::async_read_until (socket, streambuf, '\n', [self = shared_from_this ()] (boost::system::error_code error, std::size_t bytes_transferred) { std::cout << std::istream (&self->streambuf).rdbuf (); });
}
private:
boost::asio::ip::tcp::socket socket;
boost::asio::streambuf streambuf;
};
class server
{
public:
server (boost::asio::io_context &io_context, std::uint16_t port) : io_context (io_context), acceptor (io_context, boost::asio::ip::tcp::endpoint (boost::asio::ip::tcp::v4 (), port)) {}
void
async_accept ()
{
auto socket = std::make_shared<boost::asio::ip::tcp::socket> (io_context);
acceptor.async_accept (*socket, [&, socket] (boost::system::error_code error) {
std::make_shared<session> (std::move (*socket))->start ();
async_accept ();
});
}
private:
boost::asio::io_context &io_context;
boost::asio::ip::tcp::acceptor acceptor;
};
int
main ()
{
boost::asio::io_context io_context;
server srv (io_context, 15001);
srv.async_accept ();
io_context.run ();
return 0;
}
您可以在浏览器中通过 运行 "localhost:15001" 进行测试。检查它打印的服务器输出:
GET / HTTP/1.1
Host: localhost:15001
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:90.0) Gecko/20100101 Firefox/90.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Connection: keep-alive
Upgrade-Insecure-Requests: 1
Sec-Fetch-Dest: document
Sec-Fetch-Mode: navigate
Sec-Fetch-Site: none
Sec-Fetch-User: ?1
编辑:修复 liv2hak
评论中报告的错误