Clean up part 2.
This commit is contained in:
parent
360d8325f4
commit
c6851bd893
@ -2,5 +2,4 @@ cmake_minimum_required(VERSION 3.17)
|
||||
project(Project_1)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
|
||||
add_executable(Project_1 main.cpp modernize/sockets.cpp)
|
Binary file not shown.
1
cmake-build-debug/metrics.json
Normal file
1
cmake-build-debug/metrics.json
Normal file
@ -0,0 +1 @@
|
||||
[15.534375,22.479834,28.15575]
|
108
main.cpp
108
main.cpp
@ -5,95 +5,14 @@
|
||||
#include "libraries/user_input.h"
|
||||
#include "libraries/osyncstream.h"
|
||||
#include "libraries/terminal.h"
|
||||
#include "libraries/json.hpp"
|
||||
#include <chrono>
|
||||
#include <iomanip>
|
||||
#include "server.h"
|
||||
#include "project/server.h"
|
||||
#include "project/client.h"
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
*
|
||||
*/
|
||||
using json = nlohmann::json;
|
||||
|
||||
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 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{};
|
||||
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)
|
||||
{
|
||||
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)
|
||||
net_client.message_received += [start, &internal_tracker, &internal_stats](std::string& message)
|
||||
{
|
||||
auto end = std::chrono::high_resolution_clock::now();
|
||||
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
|
||||
<< "Round Trip Was " << elapsed.count() << " ms\n"
|
||||
<< hr;
|
||||
|
||||
internal_stats.emplace_back(elapsed.count()); //Stats tracking
|
||||
return true;
|
||||
};
|
||||
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)
|
||||
thread.join();
|
||||
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
BIN
project/.DS_Store
vendored
Normal file
Binary file not shown.
33
project/client.h
Normal file
33
project/client.h
Normal 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
22
project/networked.h
Normal 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
58
project/server.h
Executable 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
112
server.h
@ -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)){}
|
||||
};
|
Loading…
Reference in New Issue
Block a user