首页 > 解决方案 > 在 boost::asio 中自定义套接字/关闭系统调用

问题描述

我有一个库,它使用boost::asio. 这个库是跨平台的,并通过回调将一些操作委托给使用它的应用程序。在套接字的情况下,必须发生以下情况:

  1. 库打开一个套接字(用于出站连接)。
  2. 应用程序接收到一个允许它自定义行为的回调
  3. 库连接一个套接字并使用它
  4. 应用程序收到一个回调,允许它进行任何必要的清理
  5. 库关闭套接字

以下是我认为我可以实现这一目标的方式:

class CustomizableTcpSocket {
public:
  template <typename T, typename U>
  auto async_connect(T&& endpoint, U&& handler) {
    boost::system::error_code ec;
    socket_.open(endpoint.protocol(), ec);
    native_code_.socket_did_open(socket_.native_handle());
    return socket_.async_connect(std::forward<U>(handler));
  }

  // same for async_write_some as well
  template <typename... Args>
  auto async_read_some(Args&&... args) {
    return socket_.async_read_some(std::forward<Args>(args)...);
  }

  ~CustomizableTcpSocket() {
    if (socket_.is_open()) {
      native_code_.socket_will_close(socket_.native_handle());
    }
  }

private:
  NativeCode native_code_;
  boost::asio::ip::tcp::socket socket_;
};

我发现 asio 有时会在我的析构函数触发之前关闭套接字(在操作系统级别)。

有没有办法在 asio 实际执行之前通知我套接字关闭?

标签: c++socketsboostboost-asio

解决方案


ASIO 有一个称为处理程序跟踪的调试功能。

您可以使用它来拦截被调用的套接字闭包:

  BOOST_ASIO_HANDLER_OPERATION((reactor_.context(), "socket", &impl, impl.socket_, "close"));

只是#define BOOST_ASIO_HANDLER_OPERATION(...)到你想要调用的任何函数,并在那里检查 arg 5 == "close"

这是一个如何使用处理程序跟踪的示例。

供参考:实际close()操作并不简单。最好保持原样。


推荐阅读