diff --git a/net/asio/adc_netservice_asio.h b/net/asio/adc_netservice_asio.h index a3d34ca..b6101cc 100644 --- a/net/asio/adc_netservice_asio.h +++ b/net/asio/adc_netservice_asio.h @@ -39,6 +39,9 @@ namespace adc::impl // typedef for ASIO streambuf iterators using asio_streambuff_iter_t = asio::buffers_iterator; +// ASIO match condition result typedef +using asio_matchcond_result_t = std::pair; + template concept adc_asio_transport_proto_c = std::derived_from || std::derived_from || @@ -185,7 +188,7 @@ public: // to satisfy 'adc_netservice_c' concept using async_call_ctx_t = adc_asio_async_call_ctx_t; - static constexpr std::chrono::duration DEFAULT_ACCEPT_TIMEOUT = std::chrono::years::max(); + static constexpr std::chrono::duration DEFAULT_ACCEPT_TIMEOUT = std::chrono::seconds::max(); static constexpr std::chrono::duration DEFAULT_CONNECT_TIMEOUT = std::chrono::seconds(10); static constexpr std::chrono::duration DEFAULT_SEND_TIMEOUT = std::chrono::seconds(5); static constexpr std::chrono::duration DEFAULT_RECEIVE_TIMEOUT = std::chrono::seconds(5); @@ -395,28 +398,24 @@ public: if constexpr (std::derived_from>) { // adapt to ASIO's MatchCondition - // auto match_func = [s_res, this](IT begin, IT end) { - // *s_res = this->search(std::span(begin, end)); - // // return std::make_pair(std::get<1>(*s_res), std::get<2>(*s_res)); - // std::pair res{std::get<1>(*s_res), std::get<2>(*s_res)}; - // return res; - // }; - // auto match_func = [s_res, this](asio_streambuff_iter_t begin, asio_streambuff_iter_t end) - // { - // *s_res = this->search(std::span(&*begin, &*end)); - // // return std::make_pair(std::get<1>(*s_res), std::get<2>(*s_res)); - // auto N = std::distance(std::get<0>(*s_res), std::get<1>(*s_res)); - // std::pair res{begin + N, std::get<2>(*s_res)}; - // return res; - // }; + auto match_func = + std::function( + [s_res, this](asio_streambuff_iter_t begin, asio_streambuff_iter_t end) { + // *s_res = this->search(std::span(&*begin, &*end)); + *s_res = this->search(begin, end); - // return asio::async_read_until(_socket, _streamBuffer, std::move(match_func), - // std::move(self)); - return asio::async_read_until( - _socket, _streamBuffer, - std::bind(&AdcNetServiceASIOBase::template MatchCondition, this, - std::placeholders::_1, std::placeholders::_2, s_res), - std::move(self)); + auto N = std::distance(std::get<0>(*s_res), std::get<1>(*s_res)); + asio_matchcond_result_t res{begin + N, std::get<2>(*s_res)}; + return res; + }); + + return asio::async_read_until(_socket, _streamBuffer, std::move(match_func), + std::move(self)); + // return asio::async_read_until( + // _socket, _streamBuffer, + // std::bind(&AdcNetServiceASIOBase::template MatchCondition, this, + // std::placeholders::_1, std::placeholders::_2, s_res), + // std::move(self)); } else if constexpr (std::derived_from>) { @@ -431,8 +430,30 @@ public: } } - // here, the iterators were computed in MatchCondition called by asio::async_read_until function!!! - // std::string_view net_pack{std::get<0>(*s_res), std::get<1>(*s_res)}; + + + if constexpr (std::derived_from> || + std::derived_from>) { + auto begin_it = asio::buffers_begin(_streamBuffer.data()); + auto end_it = asio::buffers_end(_streamBuffer.data()); + + *s_res = this->search(begin_it, end_it); + + if (!std::get<2>(*s_res)) { // partial or too big packet?!! + // For these types of sockets it is an error! + // ec = std::make_error_code(std::errc::protocol_error); + // self.complete(ec, msg_t()); + start = true; + asio::post(std::move(self)); // initiate consequence socket's read operation + return; + } + } // here, the iterators were computed in MatchCondition called by asio::async_read_until + // function!!! + + timer->cancel(); // there were no errors in the asynchronous read-operation, so stop timer + size_t N = std::distance(std::get<0>(*s_res), std::get<1>(*s_res)); std::span net_pack{&*std::get<0>(*s_res), N}; @@ -440,13 +461,6 @@ public: _streamBuffer.consume(net_pack.size()); while (_streamBuffer.size()) { // search for possible additional session protocol packets - // auto begin_it = (const char*)asio_streambuff_iter_t::begin(_streamBuffer.data()); - // auto end_it = (const char*)asio_streambuff_iter_t::end(_streamBuffer.data()); - // auto begin_it = asio_streambuff_iter_t::begin(_streamBuffer.data()); - // auto end_it = asio_streambuff_iter_t::end(_streamBuffer.data()); - // auto begin_it = - // static_cast>(_streamBuffer.data().data()); - // auto end_it = begin_it + _streamBuffer.data().size(); auto begin_it = asio::buffers_begin(_streamBuffer.data()); auto end_it = asio::buffers_end(_streamBuffer.data()); @@ -470,7 +484,7 @@ public: if (isTimeout(timer, ec)) { ec = std::make_error_code(std::errc::timed_out); - } else { // an error occured in async_connect + } else { // an error occured in async_* timer->cancel(); } @@ -597,8 +611,13 @@ protected: const TimeoutT& timeout, bool arm = true) { + // TODO: now()+timeout overflow!!! auto timer = std::make_unique(obj.get_executor()); + if (timeout == std::chrono::duration::max()) { + return timer; // do not arm the timer if MAX duration are given + } + if (arm) { timer->expires_after(timeout); diff --git a/tests/adc_netservice_test.cpp b/tests/adc_netservice_test.cpp index 5aebd36..a0ce04e 100644 --- a/tests/adc_netservice_test.cpp +++ b/tests/adc_netservice_test.cpp @@ -25,7 +25,7 @@ int main() asio::ip::tcp::endpoint ept_c(asio::ip::make_address_v4("0.0.0.0"), 9999); // asio::ip::tcp::endpoint ept_c(asio::ip::address_v4::any(), 9999); - std::cout << "ADDR: " << ept_s << "\n"; + // std::cout << "ADDR: " << ept_s << "\n"; std::cout << "ADDR: " << ept_c << "\n"; asio::io_context ctx; @@ -67,7 +67,7 @@ int main() std::cout << "ACCEPT ERR: " << ec.message() << "\n"; } }, - std::chrono::minutes(10)); + std::chrono::minutes(3)); ctx.run();