Я пытаюсь написать сервер, который принимает пользовательский обработчик от пользователя, используя boost asio. Я могу вызвать операторы из обработчика async_accept, но всякий раз, когда я вызываю обработчик, полученный сервером, это приводит к segfault.
#include <boost/asio.hpp>
#include <functional>
#include <iostream>
using namespace std;
using namespace boost;
using boost::asio::ip::tcp;
class Server {
private:
asio::io_service &io_service;
tcp::acceptor acc;
tcp::endpoint endpoint;
public:
Server(asio::io_service &io) : io_service{io}, acc{io} {}
void listen(unsigned short port);
void accept(function<void()> handler);
};
void Server::listen(unsigned short port) {
endpoint.port(port);
acc.open(endpoint.protocol());
acc.set_option(tcp::acceptor::reuse_address(true));
acc.bind(endpoint);
acc.listen();
}
void Server::accept(function<void()> handler) {
tcp::socket socket(io_service);
acc.async_accept(socket, [this, h = handler](const system::error_code &error) {
cout << "Hello World" << endl;
h();
accept(h);
});
}
int main() {
asio::io_service io_service;
Server s(io_service);
s.listen(8000);
s.accept([]() { cout << "Connection Accepted" << endl; });
io_service.run();
}
Однако, когда я использую std::bind
для лямбды, я передаю его волшебным образом бежит. Я не могу понять, почему и хотел бы также знать, является ли этот подход эффективным?
void Server::accept(function<void()> handler) {
tcp::socket socket(io_service);
auto h = std::bind(handler);
acc.async_accept(socket, [this, h](const system::error_code &error) {
cout << "Hello World" << endl;
h();
accept(h);
});
}