diff --git a/net/asio/adc_netservice_asio.h b/net/asio/adc_netservice_asio.h index c63c37a..0e7faee 100644 --- a/net/asio/adc_netservice_asio.h +++ b/net/asio/adc_netservice_asio.h @@ -18,6 +18,7 @@ #include #include +#include #include #ifdef USE_OPENSSL_WITH_ASIO @@ -38,7 +39,6 @@ namespace adc::impl // typedef for ASIO streambuf iterators using asio_streambuff_iter_t = asio::buffers_iterator; - template concept adc_asio_transport_proto_c = std::derived_from || std::derived_from || @@ -219,38 +219,35 @@ public: /* asynchronuos methods */ - template TokenT, + template TokenT, traits::adc_time_duration_c TimeoutT = decltype(DEFAULT_ACCEPT_TIMEOUT)> - static auto asyncAccept(asio::io_context io_ctx, - const endpoint_t& endpoint, - TokenT&& token, - const TimeoutT& timeout = DEFAULT_ACCEPT_TIMEOUT) + auto asyncAccept(const endpoint_t& endpoint, TokenT&& token, const TimeoutT& timeout = DEFAULT_ACCEPT_TIMEOUT) { // no acceptor for UDP-sockets - if constexpr (!std::is_null_pointer_v) { + if constexpr (std::is_null_pointer_v) { static_assert(false, "INVALID TRANSPORT PROTOCOL TYPE!"); } - auto acc = acceptor_t(io_ctx); - auto sock = socket_t(io_ctx); + auto acc = acceptor_t(_ioContext); - auto timer = getDeadlineTimer(timeout); + auto timer = getDeadlineTimer(acc, timeout); return asio::async_compose( - [acc = std::move(acc), sock = std::move(sock), timer = std::move(timer), start = true, &endpoint, &io_ctx]( + [acc = std::move(acc), timer = std::move(timer), start = true, &endpoint, this]( auto& self, std::error_code ec = {}) mutable { if (!ec) { if (start) { start = false; try { - acc = acceptor_t(io_ctx, endpoint); + acc = acceptor_t(_ioContext, endpoint); + // _socket.open(asio::ip::tcp::v4()); } catch (std::system_error err) { timer->cancel(); self.complete(err.code()); return; } - return acc.async_accept(sock, std::move(self)); + return acc.async_accept(_socket, std::move(self)); } } @@ -260,9 +257,9 @@ public: timer->cancel(); } - self.complete(ec, AdcNetServiceASIOBase(std::move(sock))); + self.complete(ec); }, - token, io_ctx); + token, _ioContext); } @@ -356,7 +353,9 @@ public: adc_asio_special_comp_token, RMSGT, std::remove_cvref_t::args_t>>>; - auto s_res = std::make_shared>(); + // auto s_res = std::make_sharedtemplate search), RMSGT>>(); + auto tp = this->search(std::span()); + auto s_res = std::make_shared(); auto out_flags = std::make_shared(); @@ -385,12 +384,27 @@ 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_tuple(std::get<1>(*s_res), std::get<2>(*s_res)); + // 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; }; - return asio::async_read_until(_socket, _streamBuffer, match_func, std::move(self)); + // 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>) { @@ -412,10 +426,13 @@ 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()); - // static_cast>(_streamBuffer.data().data()); - // auto end_it = begin_it + _streamBuffer.data().size(); + // 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(); *s_res = this->search(std::span(begin_it, end_it)); @@ -450,7 +467,7 @@ public: /* blocking methods */ template - static auto accept(const endpoint_t& endpoint, const TimeoutT& timeout = DEFAULT_ACCEPT_TIMEOUT) + auto accept(const endpoint_t& endpoint, const TimeoutT& timeout = DEFAULT_ACCEPT_TIMEOUT) { std::future ftr = asyncAccept(endpoint, asio::use_future, timeout); ftr.get(); @@ -531,6 +548,17 @@ protected: asio::socket_base::shutdown_type _shutdownType = asio::socket_base::shutdown_both; + template + auto MatchCondition(asio_streambuff_iter_t begin, asio_streambuff_iter_t end, T& s_res) + { + *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; + }; + + template static std::unique_ptr getDeadlineTimer(CancelableT& obj, const TimeoutT& timeout, diff --git a/tests/adc_netservice_test.cpp b/tests/adc_netservice_test.cpp index a242593..3535b24 100644 --- a/tests/adc_netservice_test.cpp +++ b/tests/adc_netservice_test.cpp @@ -1,4 +1,5 @@ #include +#include #include "../net/adc_netproto.h" #include "../net/asio/adc_netservice_asio.h" @@ -6,7 +7,8 @@ int main() { asio::ip::tcp::endpoint ept_s(asio::ip::tcp::v4(), 9999); - asio::ip::tcp::endpoint ept_c(asio::ip::make_address_v4("127.0.0.1"), 9999); + // asio::ip::tcp::endpoint ept_c(asio::ip::make_address_v4("127.0.0.1"), 9999); + asio::ip::tcp::endpoint ept_c(asio::ip::tcp::v4(), 9999); asio::io_context ctx; @@ -18,16 +20,34 @@ int main() }; // srv.asyncAccept(ept_s, srv_ctx, std::chrono::seconds(120)); - srv.asyncConnect(ept_c, [](std::error_code ec) { + // srv.asyncConnect(ept_c, [](std::error_code ec) { + // }); + + // adc::impl::AdcNetServiceASIOBase>::contx_t s_ctx; + + // srv.asyncConnect(ept_c, s_ctx); + // auto res = srv.asyncConnect(ept_c, asio::use_awaitable); + + srv.asyncAccept(ept_c, [&srv](std::error_code ec) { + if (!ec) { + std::cout << "New connection\n"; + + srv.asyncReceive( + [](std::error_code ec, std::string msg) { + if (!ec) { + std::cout << "Received: " << msg << "\n"; + } + }, + std::chrono::minutes(3)); + } else { + std::cout << "ACCEPT ERR: " << ec.message() << "\n"; + } }); - adc::impl::AdcNetServiceASIOBase>::contx_t s_ctx; - - srv.asyncConnect(ept_c, s_ctx); - auto res = srv.asyncConnect(ept_c, asio::use_awaitable); - ctx.run(); + std::cout << "Exit!\n"; + return 0; }