@ -0,0 +1,63 @@ | |||
#ifndef __BETACORE_CLIENT_HPP__ | |||
#define __BETACORE_CLIENT_HPP__ | |||
#include <string> | |||
#include <iostream> | |||
#include <functional> | |||
#include <sstream> | |||
#include <vector> | |||
#include <stdio.h> | |||
#include <stdlib.h> | |||
#include <string.h> | |||
#include <sys/types.h> | |||
#include <netdb.h> | |||
#include <netinet/in.h> | |||
#include <unistd.h> | |||
#include "common.hpp" | |||
namespace betacore{ | |||
class Client{ | |||
private: | |||
bool _online = false; | |||
bool _running= false; | |||
char key = 'Z'; | |||
int _port; | |||
std::string _address; | |||
MODE _mode; | |||
int _client_socket; | |||
std::function<void(SHAPE &S)> _update; | |||
struct sockaddr_in _server_address; | |||
struct hostent * _server; | |||
std::string encode(const SHAPE &shape); | |||
std::string crypt(const std::string &shape); | |||
std::string raw(const SHAPE &shape); | |||
SHAPE parse(const std::string &message); | |||
SHAPE decode(const std::string &message); | |||
/** | |||
* Function for Thread for getting information from server | |||
*/ | |||
void listener(); | |||
/** | |||
* Function for Thread for sending to server | |||
*/ | |||
void sender(); | |||
void start(); | |||
void stop(); | |||
public: | |||
Client(MODE mode, int port, std::string address, std::function<void(SHAPE &S)> &update); | |||
void kill(); | |||
bool running(); | |||
void send(bool encrypt, SHAPE shape); | |||
}; | |||
} | |||
#endif |
@ -0,0 +1,23 @@ | |||
#ifndef __BETACORE_COMMON_HPP__ | |||
#define __BETACORE_COMMON_HPP__ | |||
#define BUFFER_SIZE 1024 | |||
namespace betacore | |||
{ | |||
enum SHAPE{ | |||
NONE, | |||
TRIANGLE, | |||
CIRCLE, | |||
SQUARE, | |||
PENTAGON, | |||
UNKOWN | |||
}; | |||
enum MODE | |||
{ | |||
ALICE, | |||
BOB, | |||
EVE | |||
}; | |||
} | |||
#endif |
@ -0,0 +1,38 @@ | |||
#ifndef __BETACORE_SERVER_HPP__ | |||
#define __BETACORE_SERVER_HPP__ | |||
#include <vector> | |||
#include <sys/types.h> | |||
#include <sys/socket.h> | |||
#include <netinet/in.h> | |||
#include <thread> | |||
#include <utility> | |||
#include <functional> | |||
namespace betacore | |||
{ | |||
class Server | |||
{ | |||
private: | |||
bool online = false; | |||
bool server_running= false; | |||
int port; | |||
int server_socket; | |||
std::vector<int> clients; | |||
char buffer[1024]; | |||
struct sockaddr_in server_address; | |||
std::vector<sockaddr_in> client_socket_collection; | |||
void start(); | |||
void shutdown(); | |||
void listener(); | |||
void read_socket(int client); | |||
public: | |||
Server(int port); | |||
void off(); | |||
bool running(); | |||
}; | |||
} // namespace betacore | |||
#endif |
@ -0,0 +1,159 @@ | |||
#include "../includes/client.hpp" | |||
namespace betacore | |||
{ | |||
Client::Client(MODE mode, int port, std::string address, std::function<void(SHAPE &S)> &update) : _mode(mode), | |||
_port(port), | |||
_address(address), | |||
_update(update) | |||
{ | |||
this->start(); | |||
} | |||
void Client::start() | |||
{ | |||
std::cout | |||
<< "Start" | |||
<< "\nConnecting to: " << _address << ":" <<_port | |||
<< std::endl; | |||
//Create a socket point | |||
_client_socket = socket(AF_INET, SOCK_STREAM, 0); | |||
_server = gethostbyname(_address.c_str()); | |||
if (_client_socket < 0) | |||
{ | |||
std::cout << "ERROR opening socket" << std::endl; | |||
return; | |||
} | |||
std::cout | |||
<< "Socket Open" | |||
<< std::endl; | |||
bzero((char *)&_server_address, sizeof(_server_address)); | |||
_server_address.sin_family = AF_INET; | |||
std::cout | |||
<< "AF_INT SET" | |||
<< std::endl; | |||
bcopy((char *)_server->h_addr, (char *)&_server_address.sin_addr.s_addr, _server->h_length); | |||
_server_address.sin_port = htons(_port); | |||
// Now connect to the server | |||
if (connect(_client_socket, (struct sockaddr *)&_server_address, sizeof(_server_address)) < 0) | |||
{ | |||
std::cout << "ERROR connecting" << std::endl; | |||
return; | |||
} | |||
std::cout | |||
<< "Client Connected" | |||
<< std::endl; | |||
} | |||
void Client::stop() | |||
{ | |||
std::cout | |||
<< "Stop" | |||
<< std::endl; | |||
} | |||
void Client::kill() | |||
{ | |||
std::cout | |||
<< "Kill" | |||
<< std::endl; | |||
this->_online = false; | |||
} | |||
bool Client::running() | |||
{ | |||
return this->_running; | |||
} | |||
SHAPE Client::parse(const std::string &message) | |||
{ | |||
std::stringstream stream(message); | |||
std::string tmp; | |||
std::vector<std::string> words; | |||
while (std::getline(stream, tmp, ':')) | |||
words.push_back(tmp); | |||
if (words.size() < 2) | |||
return NONE; | |||
tmp = words.at(1); | |||
SHAPE result = decode(tmp); | |||
if (result != UNKOWN) | |||
return result; | |||
if (_mode == EVE) | |||
return UNKOWN; | |||
return decode(crypt(tmp)); | |||
} | |||
SHAPE Client::decode(const std::string &shape) | |||
{ | |||
if (shape == "TRIANGLE") | |||
return TRIANGLE; | |||
if (shape == "CIRCLE") | |||
return CIRCLE; | |||
if (shape == "SQUARE") | |||
return SQUARE; | |||
if (shape == "PENTAGON") | |||
return PENTAGON; | |||
return UNKOWN; | |||
} | |||
std::string Client::crypt(const std::string &message) | |||
{ | |||
std::string output = message; | |||
for (int i = 0; i < message.size(); i++) | |||
output[i] = message[i] ^ key; | |||
return output; | |||
} | |||
std::string Client::encode(const SHAPE &shape) | |||
{ | |||
std::string message; | |||
switch (shape) | |||
{ | |||
case TRIANGLE: | |||
message = "TRIANGLE"; | |||
break; | |||
case CIRCLE: | |||
message = "CIRCLE"; | |||
break; | |||
case SQUARE: | |||
message = "SQUARE"; | |||
break; | |||
case PENTAGON: | |||
message = "PENTAGON"; | |||
break; | |||
default: | |||
message = "UNKOWN"; | |||
break; | |||
} | |||
return message; | |||
} | |||
void Client::send(bool encrypt, SHAPE shape) | |||
{ | |||
std::string message = "SHAPE:" + encrypt ? crypt(encode(shape)) : encode(shape) + ":END"; | |||
std::cout << "Sending Message: " << message << std::endl; | |||
char buffer[BUFFER_SIZE]; | |||
bzero(buffer, BUFFER_SIZE); | |||
strcpy(buffer, message.c_str()); | |||
if (write(_client_socket, buffer, strlen(buffer) < 0)) | |||
{ | |||
std::cout << "Failed send to server" << std::endl; | |||
} | |||
} | |||
void Client::listener() | |||
{ | |||
while (_online) | |||
{ | |||
// Now read server response | |||
char buffer[BUFFER_SIZE]; | |||
bzero(buffer, BUFFER_SIZE); | |||
if (read(_client_socket, buffer, BUFFER_SIZE-1) < 0) | |||
{ | |||
std::cout << "ERROR reading from socket" << std::endl; | |||
} | |||
std::string message(buffer); | |||
SHAPE shape = parse(buffer); | |||
_update(shape); | |||
} | |||
} | |||
} // namespace betacore |
@ -0,0 +1,15 @@ | |||
#include "client.hpp" | |||
#include <iostream> | |||
void test(betacore::SHAPE &s){ | |||
std::cout << "It worked" << std::endl; | |||
} | |||
int main(int argc, char * argv[]){ | |||
std::function<void(betacore::SHAPE &S)> fn= test; | |||
betacore::Client client(betacore::ALICE,4444, "localhost",fn); | |||
client.send(false, betacore::TRIANGLE); | |||
client.send(true, betacore::TRIANGLE); | |||
//s.off(); | |||
//while(client.running()){} | |||
return 0; | |||
} |
@ -0,0 +1,115 @@ | |||
#include "../includes/server.hpp" | |||
#include <iostream> | |||
#include <stdio.h> | |||
#include <stdlib.h> | |||
#include <string.h> | |||
#include <unistd.h> | |||
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; | |||
std::thread listen_thread([this] { this->listener(); } ); | |||
listen_thread.detach(); | |||
} | |||
void Server::listener() | |||
{ | |||
std::cout << "Listener "<< online << std::endl; | |||
while (online) { | |||
struct sockaddr_in client_address; | |||
listen(this->server_socket, 5); | |||
socklen_t client_socket_length = sizeof(client_address); | |||
int client_number = | |||
accept(server_socket, (struct sockaddr *)&client_address, &client_socket_length); | |||
this->client_socket_collection.push_back(client_address); | |||
this->clients.push_back(client_number); | |||
std::cout << "New Conenction"<< std::endl; | |||
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; | |||
while (online) | |||
{ | |||
if (client < 0) | |||
{ | |||
std::cout << "ERROR on accept"<< std::endl; | |||
} | |||
bzero(buffer, 256); | |||
n = read(client, buffer, 1024); | |||
if (n < 0) | |||
{ | |||
std::cout << "ERROR reading from socket"<< std::endl; | |||
} | |||
printf("Here is the message: %s\n", buffer); | |||
n = write(client, "I got your mesage\n", 18); | |||
if (n < 0) | |||
{ | |||
std::cout << "ERROR Writing socket"<< std::endl; | |||
} | |||
} | |||
} | |||
void Server::shutdown() | |||
{ | |||
std::cout << "Server is shuting down"<< std::endl; | |||
for (auto socket : clients){ | |||
std::cout | |||
<< "Closing new socket :: " | |||
<< socket | |||
<< std::endl; | |||
close(socket); | |||
} | |||
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 |
@ -0,0 +1,8 @@ | |||
#include "server.hpp" | |||
int main(int argc, char * argv[]){ | |||
betacore::Server s(4444); | |||
//s.off(); | |||
while(s.running()){} | |||
return 0; | |||
} |
@ -0,0 +1 @@ | |||
https://stackoverflow.com/questions/10673585/start-thread-with-member-function |