我正在编程UDP客户端。该协议被编写为单个请求的单个响应。我有一个发送消息的事务类,然后运行一个计时器以等待响应。如果在预期的时间内收到响应,计时器将停止并调用成功回调。否则,将调用失败回调。最后,在两种情况下都将无条件调用finish回调。
template <typename RequestType, typename ResponseType>
struct transaction{
boost::asio::io_service& _service;
boost::asio::deadline_timer _timer;
typename ResponseType::buffer_type _buff;
RequestType _request;
transaction(boost::asio::io_service& service, const RequestType& req): _service(service), _timer(service), _request(req){}
virtual ~transaction(){}
template <typename SuccessCallback, typename FailureCallback, typename FinishCallback>
void exec(boost::asio::ip::udp::endpoint& endpoint, boost::asio::ip::udp::socket& socket, unsigned wait_seconds, SuccessCallback success, FailureCallback failure, FinishCallback finish){
_timer.expires_from_now(boost::posix_time::seconds(wait_seconds));
_timer.async_wait([this, &failure, &finish](const boost::system::error_code& error){
if(!error){
std::cout << "failed to receive reply within deadline" << std::endl;
failure(_request);
finish(this);
}
});
socket.async_receive_from(boost::asio::buffer(_buff), endpoint, [this, &success, finish](const boost::system::error_code& error, std::size_t bytes_transferred){
if(!error && bytes_transferred > 0){
ResponseType reply;
reply.parse(_buff);
_timer.cancel();
success(reply);
finish(this);
}
});
socket.send_to(boost::asio::buffer(_request.buffer()), endpoint);
}
};
交易一次正常。但是,如果失败,我想重试。以下是敲门功能,该功能首次正常运行。但是在失败回调中,它将再次调用爆震,从而导致段错误。
typedef transaction<request_knock, reply_knock> transaction_knock;
void knock(boost::asio::io_service& service, boost::asio::ip::udp::endpoint& endpoint, boost::asio::ip::udp::socket& socket){
request_knock knock_request(0);
transaction_knock* knock_transaction = new transaction_knock(service, knock_request);
knock_transaction->exec(endpoint, socket, 5, [](const reply_knock& reply){
std::cout << "success " << reply._data.id << std::endl;
}, [&service, &endpoint, &socket](const request_knock& req){
// FAILURE
knock(service, endpoint, socket);
}, [](transaction_knock* transaction){
delete transaction;
});
}
以下是回溯
#0 0x00007ffff7f0f244 in pthread_mutex_lock () from /usr/lib/libpthread.so.0
#1 0x000055555559f3c8 in boost::asio::detail::posix_mutex::lock (this=0xfbad2a8c) at /usr/include/boost/asio/detail/posix_mutex.hpp:52
#2 0x00005555555a7cb4 in boost::asio::detail::scoped_lock<boost::asio::detail::posix_mutex>::scoped_lock (this=0x7fffffffe2a0, m=...)
at /usr/include/boost/asio/detail/scoped_lock.hpp:46
#3 0x00005555555a02f5 in boost::asio::detail::service_registry::do_use_service (this=0xfbad2a84, key=...,
factory=0x5555555b4666 <boost::asio::detail::service_registry::create<boost::asio::detail::deadline_timer_service<boost::asio::time_traits<boost::posix_time::ptime> >, boost::asio::io_context>(void*)>, owner=0x7ffff7bbe5c0 <_IO_2_1_stdout_>)
at /usr/include/boost/asio/detail/impl/service_registry.ipp:117
#4 0x00005555555b39da in boost::asio::detail::service_registry::use_service<boost::asio::detail::deadline_timer_service<boost::asio::time_traits<boost::posix_time::ptime> > > (this=0xfbad2a84, owner=...) at /usr/include/boost/asio/detail/impl/service_registry.hpp:39
#5 0x00005555555b2219 in boost::asio::use_service<boost::asio::detail::deadline_timer_service<boost::asio::time_traits<boost::posix_time::ptime> > > (ioc=...) at /usr/include/boost/asio/impl/io_context.hpp:39
#6 0x00005555555b021d in boost::asio::basic_io_object<boost::asio::detail::deadline_timer_service<boost::asio::time_traits<boost::posix_time::ptime> >, true>::basic_io_object (this=0x5555555e2f20, io_context=...) at /usr/include/boost/asio/basic_io_object.hpp:224
#7 0x00005555555ad795 in boost::asio::basic_deadline_timer<boost::posix_time::ptime, boost::asio::time_traits<boost::posix_time::ptime> >::basic_deadline_timer (this=0x5555555e2f20, io_context=...) at /usr/include/boost/asio/basic_deadline_timer.hpp:159
#8 0x00005555555aa4ab in transaction<request_knock, reply_knock>::transaction (this=0x5555555e2f10, service=..., req=...)
at /home/else/Projects/comet/main.cpp:111
#9 0x000055555559a90c in knock (service=..., endpoint=..., socket=...) at /home/else/Projects/comet/main.cpp:192
#10 0x000055555559a8a2 in <lambda(const request_knock&)>::operator()(const request_knock &) const (__closure=0x7fffffffe3d0, req=...)
我正在尝试找出导致崩溃的原因?