У меня есть библиотека, которая взаимодействует с сокетами TCP и UDP, используя boost::asio
. Эта библиотека является кроссплатформенной и делегирует некоторые операции приложению, использующему ее через обратные вызовы. В случае сокетов должно произойти следующее:
Вот как я думал, что могу этого добиться:
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 действительно делает это?
ASIO имеет функцию отладки под названием отслеживание обработчика.
Вы можете использовать его для перехвата закрытие сокета, которые вызываются как:
BOOST_ASIO_HANDLER_OPERATION((reactor_.context(), "socket", &impl, impl.socket_, "close"));
Просто #define BOOST_ASIO_HANDLER_OPERATION(...)
к любой функции, которую вы хотите вызвать, и там проверьте, что arg 5 == "close"
.
Вот пример о том, как использовать отслеживание обработчиков.
Для справки: фактическая операция close()
— не просто. Лучше оставить все как есть.
Спасибо, пока это, кажется, именно то, что мне нужно! Слово предупреждения для всех, кто делает это: это изменяет иерархию классов вещей внутри boost/asio
— определите макрос, используя -DBOOST_ASIO_CUSTOM_HANDLER_TRACKING = "myheader.hpp"
, иначе вы получите повреждение памяти в любом месте, где этот макрос не определен до включения boost.
Я бы посоветовал внимательно изучить документацию. stackoverflow.com/questions/818665/… может помочь.