Clean up part 2.

This commit is contained in:
Substitute 2021-02-11 02:26:38 -05:00
parent 360d8325f4
commit c6851bd893
10 changed files with 132 additions and 203 deletions

BIN
.DS_Store vendored

Binary file not shown.

View File

@ -2,5 +2,4 @@ cmake_minimum_required(VERSION 3.17)
project(Project_1) project(Project_1)
set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD 17)
add_executable(Project_1 main.cpp modernize/sockets.cpp) add_executable(Project_1 main.cpp modernize/sockets.cpp)

Binary file not shown.

View File

@ -0,0 +1 @@
[15.534375,22.479834,28.15575]

108
main.cpp
View File

@ -5,95 +5,14 @@
#include "libraries/user_input.h" #include "libraries/user_input.h"
#include "libraries/osyncstream.h" #include "libraries/osyncstream.h"
#include "libraries/terminal.h" #include "libraries/terminal.h"
#include "libraries/json.hpp"
#include <chrono> #include <chrono>
#include <iomanip> #include "project/server.h"
#include "server.h" #include "project/client.h"
#include <iostream>
#include <fstream>
using json = nlohmann::json;
/*
*
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<unsigned int>("Select Command:\n\t1. Date", "");
const auto total_clients = get_input<unsigned int>("Input Number of Clients: ", "");
std::vector<std::thread> 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) auto onClientConnected(networked& client)
{ {
@ -146,16 +65,19 @@ auto execute_as_client(std::string ipaddress, std::uint16_t port)
{ {
auto num_clients = get_input<int>("Enter number of clients. (1-25): ", "Invalid Amount", math::is_between<0, 26>); 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>); 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>);
auto internal_tracker = 0;
std::vector<std::thread> threads{}; std::vector<std::thread> threads{};
threads.reserve(num_clients); threads.reserve(num_clients);
auto internal_tracker = 0; //Stats tracking.
std::vector<double> internal_stats{};
internal_stats.reserve(num_clients);
for(int i = 0; i < num_clients; ++i) for(int i = 0; i < num_clients; ++i)
{ {
threads.emplace_back(std::thread([&]() threads.emplace_back(std::thread([&]()
{ {
client net_client{}; client net_client{};
auto start = std::chrono::high_resolution_clock::now(); auto start = std::chrono::high_resolution_clock::now();
net_client.message_received += [start, &internal_tracker](std::string& message) net_client.message_received += [start, &internal_tracker, &internal_stats](std::string& message)
{ {
auto end = std::chrono::high_resolution_clock::now(); auto end = std::chrono::high_resolution_clock::now();
std::chrono::duration<double, std::milli> elapsed = end-start; std::chrono::duration<double, std::milli> elapsed = end-start;
@ -163,7 +85,7 @@ auto execute_as_client(std::string ipaddress, std::uint16_t port)
<< message << message
<< "Round Trip Was " << elapsed.count() << " ms\n" << "Round Trip Was " << elapsed.count() << " ms\n"
<< hr; << hr;
internal_stats.emplace_back(elapsed.count()); //Stats tracking
return true; return true;
}; };
auto res = net_client.connect(ipaddress, port); auto res = net_client.connect(ipaddress, port);
@ -178,6 +100,12 @@ auto execute_as_client(std::string ipaddress, std::uint16_t port)
for(auto&& thread : threads) for(auto&& thread : threads)
thread.join(); thread.join();
sscout << "Finished!\n"; sscout << "Finished!\n";
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();
} }

BIN
project/.DS_Store vendored Normal file

Binary file not shown.

33
project/client.h Normal file
View File

@ -0,0 +1,33 @@
#pragma once
#include "../libraries/event.h"
#include "networked.h"
#include <thread>
class client : public networked
{
auto accept_message() -> void //add const later
{
while(is_valid()) /* Accept all messages */
{
auto message = receive_message();
if (message.empty() && is_valid()) //connection is closed or broken.
{
disconnect();
break;
}
message_received.execute(message);
}
}
public:
event<std::string&> message_received {};
explicit client() : networked(net::socket(AF_INET, SOCK_STREAM, 0)){}
auto connect(const std::string& ip, const port port) -> std::thread
{
const auto address = net::getaddrinfo(ip, std::to_string(port));
auto remote_address = net::getaddrinfo(ip, std::to_string(port));
if (net::connect(socket, remote_address) < 0)
return std::thread();
auto thread = std::thread(&client::accept_message, this);
return thread;
}
};

22
project/networked.h Normal file
View File

@ -0,0 +1,22 @@
#pragma once
#include "../modernize/sockets.h"
class networked
{
protected:
SOCKET socket;
public:
explicit networked(SOCKET existing)
{
socket = existing;
}
auto disconnect() -> void
{
if (!is_valid()) return; //socket is closed.
net::closesocket(socket);
socket = INVALID_SOCKET;
}
[[nodiscard]] auto receive_message() const -> std::string { if (!is_valid()) return ""; return net::recv(socket); }
auto send_message(const std::string& message) const -> void { if (!is_valid()) return; net::send(socket, message);}
[[nodiscard]] auto is_valid() const -> bool { return socket != INVALID_SOCKET; }
};

58
project/server.h Executable file
View File

@ -0,0 +1,58 @@
#pragma once
#include "../libraries/event.h"
#include "../libraries/osyncstream.h"
#include "networked.h"
#include <thread>
class server : networked
{
auto accept_clients() -> void
{
while(is_valid())
{
auto client = networked(accept(socket, nullptr, nullptr));
client_connected.execute(client);
#ifdef THREADED
std::thread(&server::accept_client_message, this, client).detach();
#else
std::thread(&server::accept_client_message, this, client).join();
#endif
}
}
auto accept_client_message(networked client) -> void //add const later
{
while(client.is_valid()) /* Accept all messages */
{
auto message = client.receive_message();
if (message.empty() && client.is_valid()) //Client could have disconnected after check but PRIOR to recv.
{
sscout << "Client Connection Lost\n";
client.disconnect();
break;
}
message_received.execute(client, message);
}
}
public:
event<networked&> client_connected {};
event<networked&, std::string&> message_received {};
auto listen(const std::string& ip, const port port) -> std::thread
{
const auto address = net::getaddrinfo(ip, std::to_string(port));
if (net::bind(socket, address) < 0)
{
sscout << "Error binding.\n";
return std::thread();
}
if (net::listen(socket) < 0)
{
sscout << "Error listening.\n";
return std::thread();
}
sscout << "Listening ... \n";
return std::thread(&server::accept_clients, this);
}
explicit server() : networked(net::socket(AF_INET, SOCK_STREAM, 0)){}
};

112
server.h
View File

@ -1,112 +0,0 @@
#pragma once
#include "modernize/sockets.h"
#include "libraries/event.h"
#include "libraries/osyncstream.h"
#include <thread>
class networked
{
protected:
SOCKET socket;
public:
explicit networked(SOCKET existing)
{
socket = existing;
}
auto disconnect() -> void
{
if (!is_valid()) return; //socket is closed.
net::closesocket(socket);
socket = INVALID_SOCKET;
}
[[nodiscard]] auto receive_message() const -> std::string { if (!is_valid()) return ""; return net::recv(socket); }
auto send_message(const std::string& message) const -> void { if (!is_valid()) return; net::send(socket, message);}
[[nodiscard]] auto is_valid() const -> bool { return socket != INVALID_SOCKET; }
};
class client : public networked
{
auto accept_message() -> void //add const later
{
while(is_valid()) /* Accept all messages */
{
auto message = receive_message();
if (message.empty() && is_valid()) //connection is closed or broken.
{
disconnect();
break;
}
message_received.execute(message);
}
}
public:
event<std::string&> message_received {};
explicit client() : networked(net::socket(AF_INET, SOCK_STREAM, 0)){}
auto connect(const std::string& ip, const port port) -> std::thread
{
const auto address = net::getaddrinfo(ip, std::to_string(port));
auto remote_address = net::getaddrinfo(ip, std::to_string(port));
if (net::connect(socket, remote_address) < 0)
return std::thread();
auto thread = std::thread(&client::accept_message, this);
return thread;
}
};
class server : networked
{
auto accept_clients() -> void
{
while(is_valid())
{
auto client = networked(accept(socket, nullptr, nullptr));
client_connected.execute(client);
#ifdef THREADED
std::thread(&server::accept_client_message, this, client).detach();
#else
std::thread(&server::accept_client_message, this, client).join();
#endif
}
}
auto accept_client_message(networked client) -> void //add const later
{
//using namespace std::chrono_literals;
//std::this_thread::sleep_for(2000ms);
while(client.is_valid()) /* Accept all messages */
{
auto message = client.receive_message();
if (message.empty() && client.is_valid()) //Client could have disconnected after check but PRIOR to recv.
{
sscout << "Client Connection Lost\n";
client.disconnect();
break;
}
message_received.execute(client, message);
}
}
public:
event<networked&> client_connected {};
event<networked&, std::string&> message_received {};
auto listen(const std::string& ip, const port port) -> std::thread
{
const auto address = net::getaddrinfo(ip, std::to_string(port));
if (net::bind(socket, address) < 0)
{
sscout << "Error binding.\n";
return std::thread();
}
if (net::listen(socket) < 0)
{
sscout << "Error listening.\n";
return std::thread();
}
sscout << "Listening ... \n";
return std::thread(&server::accept_clients, this);
}
explicit server() : networked(net::socket(AF_INET, SOCK_STREAM, 0)){}
};