#if WIN32 #define NOMINMAX #endif #include "modernize/sockets.h" #include "libraries/user_input.h" #include "libraries/osyncstream.h" #include "libraries/terminal.h" #include #include #include "server.h" /* * auto server(const addrinfo_up& address) noexcept -> void { const auto socket = net::socket(AF_INET, SOCK_STREAM, 0); net::bind(socket, address); net::listen(socket); std::cout << "[ Server Started ]" << std::endl; //below needs update. do { auto const client = accept(socket, nullptr, nullptr); if (!client) continue; printf("Got a client.\n"); auto operation = net::recv(client); try { switch (std::stoi(operation)) { case 1: net::send(client, net::system("date /t")); break; case 4: net::send(client, net::system("netstat -ant")); break; default: net::send(client, "INVALID INPUT!"); break; } } catch (std::exception&) { net::send(client, "INVALID INPUT!"); } net::send(client, "<=> T123 <=>"); net::closesocket(client); printf("Closed Client\n"); } while (true); } auto client(const addrinfo_up& address) noexcept -> void { while(true) { const auto operation = get_input("Select Command:\n\t1. Date", ""); const auto total_clients = get_input("Input Number of Clients: ", ""); std::vector threads; for(auto i = 0u; i < total_clients; ++i) { const auto prefix = "[client " + std::to_string(i) + "]: "; try { threads.emplace_back(std::thread([=, &address]() { sscout << prefix << "started" << std::endl; const auto socket = net::socket(AF_INET, SOCK_STREAM, 0); net::connect(socket, address); net::send(socket, std::to_string(operation)); sscout << prefix << "sent command" << std::endl; const auto& response = net::recv(socket); sscout << prefix << "got response\n" << prefix << response << std::endl; net::closesocket(socket); sscout << prefix << "closed" << std::endl; })); } catch (std::exception&) { sscout << prefix << " failed to init " << std::endl; } } for (auto& thread : threads) thread.join(); } } * */ auto onClientConnected(networked& client) { sscout << "Accepted Client on Server.\n"; using namespace std::chrono_literals; auto start = std::chrono::high_resolution_clock::now(); //std::this_thread::sleep_for(2000ms); return true; } auto onClientMessaged(networked& client, std::string& message) { try { int operation = std::stoi(message); sscout << "OPCode is " << operation << ".\n"; switch(operation) { case 1: client.send_message(net::system("date")); break; case 4: client.send_message(net::system("netstat -ant")); break; default: break; } }catch(std::invalid_argument& invalid_number) { sscout << "Invalid OPCode, Ignored.\n"; } client.disconnect(); return true; } auto get_ip_port(int mode) { std::string ipaddress{}; std::uint16_t port{}; if (mode == 1) ipaddress = "0.0.0.0"; else ipaddress = get_input("Enter IP: "); port = get_input("Enter Port:"); return std::make_tuple(mode == 1 ? "Server" : mode == 2 ? "Client" : "Unknown", ipaddress, port); } auto execute_as_client(std::string ipaddress, std::uint16_t port) { auto num_clients = get_input("Enter number of clients. (1-25): ", "Invalid Amount", math::is_between<0, 26>); auto operation = get_input("Pick Command\n\t1. Date\n\t2. \n\t3. \n\t4. Netstat\n:>", "Invalid Selection", math::is_between<0, 5>); auto internal_tracker = 0; std::vector threads{}; threads.reserve(num_clients); for(int i = 0; i < num_clients; ++i) { threads.emplace_back(std::thread([&]() { client net_client{}; auto start = std::chrono::high_resolution_clock::now(); net_client.message_received += [start, &internal_tracker](std::string& message) { auto end = std::chrono::high_resolution_clock::now(); std::chrono::duration elapsed = end-start; sscout << internal_tracker << math::numerical_suffix(internal_tracker++) << " client response\n" << message << "Round Trip Was " << elapsed.count() << " ms\n" << hr; return true; }; auto res = net_client.connect(ipaddress, port); if (res.joinable()) { net_client.send_message(std::to_string(operation)); res.join(); } })); } sscout << "All clients connected.\n" << hr; for(auto&& thread : threads) thread.join(); sscout << "Finished!\n"; } int main() { net::prologue(); const auto mode = get_input("Select Mode\n\t1. Server\n\t2. Client\n>:", "Invalid Choice!", math::is_between<0, 3>); while (true) { auto[prefix, ipaddress, port] = get_ip_port(mode); sscout << prefix << " selected, ip/port is " << ipaddress << "/" << port << ".\n"; if (mode == 2) { execute_as_client(ipaddress, port); } else { server net_server{}; net_server.client_connected += onClientConnected; net_server.message_received += onClientMessaged; net_server.listen(ipaddress, port).join(); } } }