2021-02-09 23:02:05 -05:00
|
|
|
#if WIN32
|
|
|
|
#define NOMINMAX
|
|
|
|
#endif
|
|
|
|
#include "sockets.h"
|
|
|
|
#include "user_input.h"
|
|
|
|
#include <chrono>
|
2021-02-10 16:32:59 -05:00
|
|
|
#include <iomanip>
|
2021-02-09 23:02:05 -05:00
|
|
|
#include "server.h"
|
|
|
|
#include "osyncstream.h"
|
|
|
|
#include "switch_expression.h"
|
2021-02-10 16:32:59 -05:00
|
|
|
#include <sys/ioctl.h>
|
|
|
|
#include "helpers/terminal.h"
|
2021-02-09 23:02:05 -05:00
|
|
|
/*
|
|
|
|
*
|
|
|
|
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();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
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";
|
|
|
|
client.send_message("thanks for the message!");
|
|
|
|
}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 16:32:59 -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", "Invalid Selection", math::is_between<0, 2>);
|
|
|
|
auto internal_tracker = 0;
|
|
|
|
std::vector<std::thread> threads{};
|
|
|
|
threads.reserve(num_clients);
|
|
|
|
auto [width, _] = terminal_size();
|
|
|
|
for(int i = 0; i < num_clients; ++i)
|
2021-02-09 23:02:05 -05:00
|
|
|
{
|
2021-02-10 16:32:59 -05:00
|
|
|
threads.emplace_back(std::thread([&, i]()
|
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();
|
|
|
|
net_client.message_received += [=, &internal_tracker](std::string& message)
|
|
|
|
{
|
|
|
|
auto end = std::chrono::high_resolution_clock::now();
|
|
|
|
std::chrono::duration<double, std::milli> elapsed = end-start;
|
|
|
|
sscout << "message for " << internal_tracker << math::numerical_suffix(internal_tracker++) << " of which is " << message << ".\n"
|
|
|
|
<< "Round Trip Was " << elapsed.count() << " ms\n"
|
|
|
|
<< hl;
|
|
|
|
|
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
|
|
|
}));
|
|
|
|
}
|
|
|
|
sscout << "All clients connected.\n";
|
|
|
|
for(auto&& thread : threads)
|
|
|
|
thread.join();
|
|
|
|
sscout << "Finished!\n";
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int main()
|
|
|
|
{
|
|
|
|
net::prologue();
|
|
|
|
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);
|
|
|
|
sscout << prefix << " selected, ip/port is " << ipaddress << "/" << port << ".\n";
|
|
|
|
if (mode == 2) {
|
|
|
|
execute_as_client(ipaddress, port);
|
|
|
|
continue;
|
|
|
|
for (int i = 0; i < 10; ++i) {
|
|
|
|
client net_client{};
|
|
|
|
net_client.message_received += [](std::string &what) {
|
|
|
|
sscout << "GOT " << what << ".\n";
|
|
|
|
return true;
|
|
|
|
};
|
|
|
|
auto res = net_client.connect(ipaddress, port);
|
|
|
|
if (res.joinable()) {
|
|
|
|
net_client.send_message(std::string("!Hello! from") + std::to_string(i) + "\n");
|
|
|
|
res.join();
|
|
|
|
} else {
|
|
|
|
sscout << "NO NET\n";
|
|
|
|
}
|
|
|
|
net_client.disconnect();
|
2021-02-09 23:02:05 -05:00
|
|
|
}
|
2021-02-10 16:32:59 -05:00
|
|
|
}
|
|
|
|
else{
|
|
|
|
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
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
auto listen_server = []()
|
|
|
|
{
|
|
|
|
server srv{};
|
|
|
|
srv.client_connected += onClientConnected;
|
|
|
|
srv.message_received += onClientMessaged;
|
|
|
|
auto thread = srv.listen("0.0.0.0", 80);
|
|
|
|
if(thread.joinable())
|
|
|
|
{
|
|
|
|
thread.join();
|
|
|
|
}else{
|
|
|
|
sscout << "Thread is bad!\n";
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
net::epilogue();
|
|
|
|
return 0;
|
|
|
|
/*
|
|
|
|
*
|
|
|
|
const auto selection = get_input<int>("Select Mode\n\t1. Server\n\t2. Client\n>:", "Invalid Choice!", [](const auto x) {return x > 0 && x < 3; });
|
|
|
|
|
|
|
|
auto address = std::string("0.0.0.0");
|
|
|
|
auto port = 0_p;
|
|
|
|
addrinfo_up address_binding{};
|
|
|
|
while(!address_binding.get())
|
|
|
|
{
|
|
|
|
if (selection == 2)
|
|
|
|
address = get_input<std::string>("Enter Remote IP (aaa.bbb.ccc.ddd): ", "");
|
|
|
|
port = get_input<unsigned short>("Enter Port: ", "");
|
|
|
|
address_binding = net::getaddrinfo(address, std::to_string(port));
|
|
|
|
}
|
|
|
|
|
|
|
|
try
|
|
|
|
{
|
|
|
|
std::cout << "You have selected " << (selection == 1 ? "Server" : "Client") << std::endl;
|
|
|
|
std::cout << "Address: " << address << ":" << port << std::endl;
|
|
|
|
}catch(std::exception&){}
|
|
|
|
|
|
|
|
|
|
|
|
if (selection == 2)
|
|
|
|
client(address_binding);
|
|
|
|
else
|
|
|
|
listen_server(address_binding);
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
net::epilogue();
|
|
|
|
}
|
|
|
|
|
|
|
|
|