在boost :: asio中自定义套接字/关闭系统调用

时间:2019-05-27 11:19:30

标签: c++ sockets boost boost-asio

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

  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有时会关闭套接字(在OS级别)。

有没有一种方法可以通知我在 之前确实关闭了套接字?

1 个答案:

答案 0 :(得分:1)

ASIO具有称为handler tracking的调试功能。

您可以使用它来拦截socket closures,其调用方式为:

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

只需#define BOOST_ASIO_HANDLER_OPERATION(...)到要调用的任何函数,然后在其中检查arg 5 == "close"

这是example,介绍了如何使用处理程序跟踪。

供参考:实际的close()操作是not straightforward。最好保持原状。