#include "../includes/server.hpp"
|
|
|
|
namespace betacore
|
|
{
|
|
Server::Server(int port)
|
|
{
|
|
this->port = port;
|
|
std::cout << "And so it begins..." << std::endl;
|
|
this->start();
|
|
}
|
|
void Server::start()
|
|
{
|
|
this->server_socket = socket(AF_INET, SOCK_STREAM, 0);
|
|
if (this->server_socket < 0)
|
|
{
|
|
std::cout << "ERROR on opening socket" << std::endl;
|
|
return;
|
|
}
|
|
std::cout << "Socket Connected" << std::endl;
|
|
|
|
bzero((char *)&server_address, sizeof(server_address));
|
|
|
|
server_address.sin_family = AF_INET;
|
|
server_address.sin_addr.s_addr = INADDR_ANY;
|
|
server_address.sin_port = htons(this->port);
|
|
|
|
if (bind(
|
|
server_socket,
|
|
(struct sockaddr *)&server_address,
|
|
sizeof(server_address)) < 0)
|
|
{
|
|
std::cout << "ERROR on binding " << std::endl;
|
|
return;
|
|
}
|
|
std::cout << "Bound" << std::endl;
|
|
online = true;
|
|
server_running = true;
|
|
std::cout << "Server is online" << std::endl;
|
|
signal(SIGPIPE, SIG_IGN); // Prevents issue with sig kill on client
|
|
std::thread listen_thread([this] { this->listener(); });
|
|
listen_thread.detach();
|
|
}
|
|
void Server::listener()
|
|
{
|
|
std::cout << "Listener " << online << std::endl;
|
|
struct sockaddr_in client_address;
|
|
listen(this->server_socket, 10);
|
|
while (online)
|
|
{
|
|
|
|
socklen_t client_socket_length = sizeof(client_address);
|
|
int client_number =
|
|
accept(server_socket, (struct sockaddr *)&client_address, &client_socket_length);
|
|
this->clients.push_back(client_number);
|
|
std::cout << "New Conenction" << std::endl;
|
|
if (client_number < 0)
|
|
{
|
|
std::cout << "ERROR on accept" << std::endl;
|
|
continue;
|
|
}
|
|
std::thread socket_thread([this, client_number] { this->read_socket(client_number); });
|
|
socket_thread.detach();
|
|
}
|
|
this->shutdown();
|
|
}
|
|
void Server::read_socket(int client)
|
|
{
|
|
std::cout
|
|
<< "Ready To Read "
|
|
<< client
|
|
<< std::endl;
|
|
int n;
|
|
char buffer[BUFFER_LENGTH];
|
|
while (online &&
|
|
std::find(clients.begin(), clients.end(), client) != clients.end())
|
|
{
|
|
|
|
bzero(buffer, BUFFER_LENGTH);
|
|
|
|
n = read(client, buffer, BUFFER_LENGTH - 1);
|
|
|
|
if (n < 0)
|
|
{
|
|
std::cout << "ERROR reading from socket" << std::endl;
|
|
break;
|
|
}
|
|
this->forward_message(client, buffer);
|
|
}
|
|
std::cout << "Closing Connection for " << client << std::endl;
|
|
clients.erase(
|
|
std::remove(clients.begin(), clients.end(), client), clients.end());
|
|
close(client);
|
|
}
|
|
void Server::forward_message(int client, char buffer[BUFFER_LENGTH])
|
|
{
|
|
std::cout << "forward message form " << client << std::endl;
|
|
int n;
|
|
int error = 0;
|
|
|
|
for (int c : clients)
|
|
{
|
|
if (c == client)
|
|
continue;
|
|
std::cout
|
|
<< "forward message form "
|
|
<< client
|
|
<< "to "
|
|
<< c
|
|
<< std::endl;
|
|
n = write(c, buffer, strlen(buffer));
|
|
|
|
if (n < 0)
|
|
{
|
|
std::cout << "ERROR Writing socket to " << c << std::endl;
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
void Server::shutdown()
|
|
{
|
|
std::cout << "Server is shuting down" << std::endl;
|
|
|
|
std::cout << "Closing server socket" << std::endl;
|
|
close(this->server_socket);
|
|
server_running = false;
|
|
}
|
|
void Server::off()
|
|
{
|
|
this->online = false;
|
|
}
|
|
bool Server::running()
|
|
{
|
|
return this->server_running;
|
|
}
|
|
|
|
} // namespace betacore
|