ClientServerProject/main.cpp

129 lines
4.1 KiB
C++
Raw Normal View History

2021-02-09 23:02:05 -05:00
#if WIN32
#define NOMINMAX
#endif
2021-02-10 23:25:56 -05:00
#include "modernize/sockets.h"
#include "libraries/user_input.h"
#include "libraries/osyncstream.h"
#include "libraries/terminal.h"
2021-02-11 02:26:38 -05:00
#include "libraries/json.hpp"
2021-02-09 23:02:05 -05:00
#include <chrono>
2021-02-11 02:26:38 -05:00
#include "project/server.h"
#include "project/client.h"
#include <iostream>
#include <fstream>
2021-02-10 23:25:56 -05:00
2021-02-11 02:26:38 -05:00
using json = nlohmann::json;
2021-02-09 23:02:05 -05:00
2021-02-10 16:32:59 -05:00
auto onClientConnected(networked& client)
2021-02-09 23:02:05 -05:00
{
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)
{
2021-02-10 16:32:59 -05:00
try
{
int operation = std::stoi(message);
sscout << "OPCode is " << operation << ".\n";
2021-02-10 23:25:56 -05:00
switch(operation)
{
case 1:
client.send_message(net::system("date"));
break;
case 4:
client.send_message(net::system("netstat -ant"));
break;
default:
break;
}
2021-02-10 16:32:59 -05:00
}catch(std::invalid_argument& invalid_number)
{
sscout << "Invalid OPCode, Ignored.\n";
}
2021-02-09 23:02:05 -05:00
client.disconnect();
return true;
}
2021-02-10 16:32:59 -05:00
auto get_ip_port(int mode)
2021-02-09 23:02:05 -05:00
{
2021-02-10 16:32:59 -05:00
std::string ipaddress{};
std::uint16_t port{};
if (mode == 1)
ipaddress = "0.0.0.0";
else
ipaddress = get_input<std::string>("Enter IP: ");
port = get_input<std::uint16_t>("Enter Port:");
return std::make_tuple(mode == 1 ? "Server" : mode == 2 ? "Client" : "Unknown", ipaddress, port);
2021-02-09 23:02:05 -05:00
}
2021-02-10 16:32:59 -05:00
auto execute_as_client(std::string ipaddress, std::uint16_t port)
2021-02-09 23:02:05 -05:00
{
2021-02-10 23:25:56 -05:00
auto num_clients = get_input<int>("Enter number of clients. (1-25): ", "Invalid Amount", math::is_between<0, 26>);
auto operation = get_input<int>("Pick Command\n\t1. Date\n\t2. \n\t3. \n\t4. Netstat\n:>", "Invalid Selection", math::is_between<0, 5>);
2021-02-10 16:32:59 -05:00
std::vector<std::thread> threads{};
threads.reserve(num_clients);
2021-02-11 02:26:38 -05:00
auto internal_tracker = 0; //Stats tracking.
std::vector<double> internal_stats{};
internal_stats.reserve(num_clients);
2021-02-10 16:32:59 -05:00
for(int i = 0; i < num_clients; ++i)
2021-02-09 23:02:05 -05:00
{
2021-02-10 23:25:56 -05:00
threads.emplace_back(std::thread([&]()
2021-02-09 23:02:05 -05:00
{
client net_client{};
2021-02-10 16:32:59 -05:00
auto start = std::chrono::high_resolution_clock::now();
2021-02-11 02:26:38 -05:00
net_client.message_received += [start, &internal_tracker, &internal_stats](std::string& message)
2021-02-10 16:32:59 -05:00
{
auto end = std::chrono::high_resolution_clock::now();
std::chrono::duration<double, std::milli> elapsed = end-start;
2021-02-10 23:25:56 -05:00
sscout << internal_tracker << math::numerical_suffix(internal_tracker++) << " client response\n"
<< message
<< "Round Trip Was " << elapsed.count() << " ms\n"
<< hr;
2021-02-11 02:26:38 -05:00
internal_stats.emplace_back(elapsed.count()); //Stats tracking
2021-02-09 23:02:05 -05:00
return true;
};
2021-02-10 16:32:59 -05:00
auto res = net_client.connect(ipaddress, port);
if (res.joinable())
2021-02-09 23:02:05 -05:00
{
2021-02-10 16:32:59 -05:00
net_client.send_message(std::to_string(operation));
res.join();
2021-02-09 23:02:05 -05:00
}
2021-02-10 16:32:59 -05:00
}));
}
2021-02-10 23:25:56 -05:00
sscout << "All clients connected.\n" << hr;
2021-02-10 16:32:59 -05:00
for(auto&& thread : threads)
thread.join();
sscout << "Finished!\n";
2021-02-11 02:26:38 -05:00
json metrics_json = internal_stats;
std::ofstream metrics;
metrics.open ("metrics.json", std::ios::out | std::ios::trunc); //again, metrics data
metrics << metrics_json;
metrics.close();
2021-02-10 16:32:59 -05:00
}
2021-02-10 23:25:56 -05:00
int main() {
2021-02-10 16:32:59 -05:00
net::prologue();
2021-02-10 23:25:56 -05:00
const auto mode = get_input<int>("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);
2021-02-10 16:32:59 -05:00
sscout << prefix << " selected, ip/port is " << ipaddress << "/" << port << ".\n";
if (mode == 2) {
execute_as_client(ipaddress, port);
2021-02-10 23:25:56 -05:00
} else {
2021-02-10 16:32:59 -05:00
server net_server{};
net_server.client_connected += onClientConnected;
net_server.message_received += onClientMessaged;
net_server.listen(ipaddress, port).join();
2021-02-09 23:02:05 -05:00
}
}
2021-02-10 23:25:56 -05:00
}