[英]Unable to pass std::function into boost::asio async_accept handler
我正在嘗試編寫一個服務器,它使用 boost asio 從用戶那里獲取一個自定義處理程序。 我可以從 async_accept 處理程序內部調用語句,但是每當我調用服務器接收到的處理程序時,它都會導致段錯誤。
#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
到 lambda 時,我通過它神奇地運行。 我無法理解為什么,也想知道這種方法是否有效?
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);
});
}
問題不在於處理程序。
未定義的行為是由將懸空引用作為局部變量訪問socket
引起的。
您調用async_accept
,它通過引用將套接字作為第一個參數:根據官方參考,調用者(您)有責任延長其生命周期,直到調用處理程序:
接受新連接的套接字。 對等體 object 的所有權由調用者保留,它必須保證在調用處理程序之前它是有效的。
您應該將套接字包裝在某種智能指針中,然后將此指針傳遞給 lambda 以延長其壽命:
std::shared_ptr<tcp::socket> socket = std::make_shared<tcp::socket>(io_service);
acc.async_accept(*socket, [this, h = handler, socket](const system::error_code &error) {
我希望,您知道async_XXX
立即返回,因此當 function 返回時,套接字也會被刪除。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.