From eb5bcc1f1c7175bd83ed2062c0c2dc8498d641d0 Mon Sep 17 00:00:00 2001 From: Joon Park <5825014+jpark730@users.noreply.github.com> Date: Mon, 2 Mar 2020 22:20:01 -0500 Subject: [PATCH] .. --- 3rdParty/asio/CMakeLists.txt | 1 + Source/Server_net/connection.h | 11 +- Source/Server_net/mmo_server.cpp | 1 + Source/Server_net/network.cpp | 11 +- Source/Server_net/network.h | 127 ++++++++---------- .../chat_client_asio/Source/chat_client.cpp | 15 ++- 6 files changed, 90 insertions(+), 76 deletions(-) diff --git a/3rdParty/asio/CMakeLists.txt b/3rdParty/asio/CMakeLists.txt index 160978a..c7f7dd8 100644 --- a/3rdParty/asio/CMakeLists.txt +++ b/3rdParty/asio/CMakeLists.txt @@ -2,6 +2,7 @@ SET( DEFINE ASIO_STANDALONE ASIO_SEPARATE_COMPILATION _WIN32_WINNT=0x0601 +_SILENCE_ALL_CXX17_DEPRECATION_WARNINGS ) SET( INCLUDE ) diff --git a/Source/Server_net/connection.h b/Source/Server_net/connection.h index c6cba38..966e6a1 100644 --- a/Source/Server_net/connection.h +++ b/Source/Server_net/connection.h @@ -138,7 +138,7 @@ namespace server } template - auto async_recv_helper(socket_type& socket, buffer_type&& buffer) -> std::future + auto async_recv_helper(socket_type& socket, buffer_type buffer) -> std::future { try { @@ -148,17 +148,19 @@ namespace server } } - catch (const std::exception & exception) + catch (const std::exception & /*exception*/) { - printf("exception: %s", exception.what()); + printf("connection %d closed.", id); + //printf("exception: %s", exception.what()); } } auto async_recv() { auto buffer = asio::buffer(rdata, 5); - async_recv_helper(socket, std::move(buffer)); + async_recv_helper(socket, asio::buffer(rdata, 5)); } +#if 0 //*/ asio::awaitable async_read() { @@ -184,6 +186,7 @@ namespace server printf("exception: %s", e.what()); } } +#endif }; static_assert(std::is_nothrow_move_constructible::value); diff --git a/Source/Server_net/mmo_server.cpp b/Source/Server_net/mmo_server.cpp index e85ed3a..160fb96 100644 --- a/Source/Server_net/mmo_server.cpp +++ b/Source/Server_net/mmo_server.cpp @@ -44,6 +44,7 @@ namespace mmo_server }; core::spawn_network_service("127.0.0.1", port, 300, accept_handler); + core::spawn_network_service("127.0.0.1", port + 1, 300, accept_handler); //core::async_accept("127.0.0.1", port, accept_handler, false); core::spawn_worker_threads(2); diff --git a/Source/Server_net/network.cpp b/Source/Server_net/network.cpp index 628adbd..1a82d81 100644 --- a/Source/Server_net/network.cpp +++ b/Source/Server_net/network.cpp @@ -14,7 +14,8 @@ namespace server std::vector connection_pool2; connection_pool connection_pool3; - std::vector network_services; + std::list network_services; + bool network_services_running; @@ -66,6 +67,7 @@ namespace server [i]() { io_context.run(); + printf("%s exited.\n", worker_threads[i].name.c_str()); }); } @@ -80,11 +82,18 @@ namespace server void start_network(int thread_count) { + assert(!network_services_running); + spawn_worker_threads(thread_count); } void stop_network() { + assert(network_services_running); + for (auto& i : network_services) + { + i.stop_signal = true; + } stop_worker_threads(); } diff --git a/Source/Server_net/network.h b/Source/Server_net/network.h index cb69ac8..7a1c337 100644 --- a/Source/Server_net/network.h +++ b/Source/Server_net/network.h @@ -68,12 +68,15 @@ namespace server lambda accept_handler; asio::error_code error_code; - asio::ip::tcp::acceptor acceptor; + asio::ip::tcp::acceptor& acceptor; + std::vector& connection_pool; + + tcp_connection* return_value; //asio::ip::tcp::socket socket; - async_accept_frame(std::string ip, unsigned short port, lambda& accept_handler) : - ip(ip), port(port), accept_handler(accept_handler), - acceptor(io_context, { asio::ip::address::from_string(ip), port }){} + async_accept_frame(asio::ip::tcp::acceptor& acceptor, std::vector& connection_pool, std::string ip, unsigned short port, lambda& accept_handler) : + ip(ip), port(port), accept_handler(accept_handler), acceptor(acceptor), connection_pool(connection_pool) + {} bool await_ready() { @@ -82,99 +85,81 @@ namespace server void await_suspend(std::experimental::coroutine_handle<> coro) { - acceptor.async_accept([this, coro](auto error_code, auto socket) { this->error_code = error_code; - connection_pool2.emplace_back(std::move(socket)); - coro.resume(); - }); + acceptor.async_accept([this, coro](auto error_code, auto socket) + { + this->error_code = error_code; + + auto new_connection = new tcp_connection(std::move(socket)); + + return_value = nullptr; + uint32 id = 0; + + for (auto& i : this->connection_pool) + { + if (!i) + { + i = new_connection; + i->id = id; + return_value = i; + break; + } + id++; + } + + coro.resume(); + }); } - tcp_connection& await_resume() + tcp_connection* await_resume() { if (error_code) { throw asio::system_error(error_code); } - return connection_pool2.back(); + return return_value; } - /* - auto async_accept() -> std::future - { - - } - */ - - /* - asio::awaitable operator()() - { - auto executor = co_await asio::this_coro::executor; - asio::ip::tcp::acceptor acceptor(executor, { asio::ip::address::from_string(ip), port }); - while (true) - { - asio::ip::tcp::socket socket = co_await acceptor.async_accept(asio::use_awaitable); - auto executor = socket.get_executor(); - - connection_pool.emplace_back(std::move(socket)); - - try - { - //connection_pool.back().socket.async_receive(asio::buffer(connection_pool.back().rdata, 12), [this](auto error_code, auto bytes_read) { }); - - connection_pool.back().async_recv(); - /* - asio::co_spawn(executor, - []() - { - return connection_pool.back().async_read(); - }, asio::detached); - //*/ - /* - } - catch (std::exception & e) - { - printf("exception: %s", e.what()); - } - - - accept_handler(); - } - } - */ - - }; - /* - template - auto spawn_async_acceptor(std::string ip, unsigned short port, lambda& accept_handler) - { - asio::co_spawn(io_context, async_acceptor(ip, port, accept_handler), asio::detached); - } - */ - struct async_network_service { + std::string ip; + unsigned short port; std::vector connection_pool; + uint32 connection_count; asio::ip::tcp::acceptor acceptor; + volatile bool stop_signal; template async_network_service(std::string ip, uint16 port, uint16 max_connection_count, lambda& accept_handler) : - acceptor(io_context, { asio::ip::address::from_string(ip), port }) {} + ip(ip), port(port), connection_count(0), acceptor(io_context, { asio::ip::address::from_string(ip), port }), + stop_signal(false) { - async_accept(ip, port, accept_handler, false); + connection_pool.resize(max_connection_count); + begin_async_accept(ip, port, accept_handler, stop_signal); } template - auto async_accept(std::string ip, unsigned short port, lambda& accept_handler, bool stop_signal) -> std::future + auto begin_async_accept(std::string ip, unsigned short port, lambda& accept_handler, volatile bool& stop_signal) -> std::future { try { - while (true) + while (!stop_signal) { - auto& new_connection = co_await async_accept_frame(ip, port, accept_handler); + auto new_connection = co_await async_accept_frame(acceptor, connection_pool, ip, port, accept_handler); - new_connection.async_recv(); + connection_count++; + + if (new_connection) + { + printf("new connection accepted: %d from %s:%d\n", new_connection->id, new_connection->address, port); + new_connection->async_recv(); + } + else + { + printf("new connection rejected, connection_count: %d.\n", connection_count); + } //co_await printf("something\n"); } } @@ -186,11 +171,13 @@ namespace server }; - extern std::vector network_services; + extern std::list network_services; + extern bool network_services_running; template void spawn_network_service(std::string ip, uint16 port, uint16 max_connection_count, lambda& accept_handler) { + assert(!network_services_running); network_services.emplace_back(ip, port, max_connection_count, accept_handler); } diff --git a/Source/chat_client_asio/Source/chat_client.cpp b/Source/chat_client_asio/Source/chat_client.cpp index ae6af03..5a77f2b 100644 --- a/Source/chat_client_asio/Source/chat_client.cpp +++ b/Source/chat_client_asio/Source/chat_client.cpp @@ -226,7 +226,12 @@ int main(int argc, char* argv[]) std::thread t([&io_context]() { io_context.run(); }); std::vector sockets; - sockets.resize(200); + sockets.reserve(200); + + for (int i = 0; i < 200; i++) + { + sockets.emplace_back(io_context); + } for (int i = 0; i < 100; i++) { @@ -243,7 +248,14 @@ int main(int argc, char* argv[]) }); } + io_context.run(); + for (;;) + { + Sleep(1000); + } + + /* char line[chat_message::max_body_length + 1]; while (std::cin.getline(line, chat_message::max_body_length + 1)) { @@ -258,6 +270,7 @@ int main(int argc, char* argv[]) } c.close(); + */ t.join(); } catch (std::exception & e)