簡體   English   中英

無法將 std::function 傳遞到 boost::asio async_accept 處理程序

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM