@ -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 |