我是一名自学成才的 C++ 程序员,试图学习更多知识。
我正在尝试修改位于此处的 boost ssl 示例:
https://www.boost.org/doc/libs/1_82_0/doc/html/boost_asio/example/cpp11/ssl/server.cpp
我正在使用 g++ 编译器和 c++20
服务器类中的do_accept()方法中有一个lambda函数:
acceptor_.async_accept(
[this](const boost::system::error_code& error, tcp::socket socket)
{
if (!error)
{
std::make_shared<session>(
boost::asio::ssl::stream<tcp::socket>(
std::move(socket), context_))->start();
}
do_accept();
});
我想将 lambda 函数更改为类方法。
我的方法是:
void server::acceptHandler(const boost::system::error_code& error, tcp::socket socket) {
...
}
当我尝试替换为: Acceptor_.async_accept(boost::bind(&server::acceptHandler, this, boost::asio::placehoders::error, tcp::socket));
我在 tcp::socket 之后的 ')' 上收到“错误:')' 标记之前预期的主表达式”
我也尝试过: Acceptor_.async_accept(boost::bind(&server::acceptHandler, this, boost::asio::placehoders::error, boost::placeholders:_2))
我得到:“错误:使用已删除的函数 'boost::asio::basic_stream_socket
将 lambda 函数更改为方法函数的正确方法是什么。
我想象了一些周围的代码:
住在科里鲁
#include <boost/asio.hpp>
#include <boost/asio/ssl.hpp>
#include <iostream>
namespace asio = boost::asio;
namespace ssl = asio::ssl;
using asio::ip::tcp;
struct session : std::enable_shared_from_this<session> {
session(boost::asio::ssl::stream<tcp::socket> s) : stream_(std::move(s)) {}
void start() {
std::cout << "Accepted connection from " << stream_.lowest_layer().remote_endpoint() << "\n";
stream_.async_handshake(ssl::stream_base::server,
[self = shared_from_this()](boost::system::error_code ec) {
if (!ec) {
self->do_read();
} else {
std::cerr << "Handshake failed: " << ec.message() << "\n";
}
});
}
private:
void do_read() {
stream_.async_read_some(
asio::buffer(data_),
[self = shared_from_this()](boost::system::error_code ec, size_t bytes_transferred) {
if (!ec) {
std::cout << "Received " << bytes_transferred << " bytes\n";
self->do_read();
} else {
std::cerr << "Read failed: " << ec.message() << "\n";
}
});
}
ssl::stream<tcp::socket> stream_;
std::array<char, 1024> data_;
};
struct Server {
Server(asio::any_io_executor ex, uint16_t port) : acc_(ex, {{}, port}) {
// TODO load certificate and private key
do_accept();
}
private:
void do_accept() {
acc_.async_accept([this](boost::system::error_code const& error, tcp::socket socket) {
if (!error) {
std::make_shared<session>(ssl::stream<tcp::socket>(std::move(socket), context_))->start();
}
do_accept();
});
}
tcp::acceptor acc_;
ssl::context context_{ssl::context::tlsv12};
};
int main() {
asio::thread_pool ctx;
Server srv(ctx.get_executor(), 8989);
ctx.join();
}
因为我将证书留给读者作为练习,所以这是关于它可以做什么:
现在,我不知道你为什么想要它,但你可以:
void do_accept() {
acc_.async_accept(std::bind( //
&Server::on_accept, this, std::placeholders::_1, std::placeholders::_2));
}
void on_accept(boost::system::error_code const& error, tcp::socket socket) {
if (!error) {
std::make_shared<session>(ssl::stream<tcp::socket>(std::move(socket), context_))->start();
}
do_accept();
}
请注意,
tcp::socket
是一种类型,而不是占位符。