Throwing exceptions

dev v0.1_beta
marcelb 1 year ago
parent 3bbfef613a
commit 31091dcbec
  1. 13
      README.md
  2. 20
      lib/tcp_socket.hpp
  3. 124
      src/tcp_socket.cpp
  4. 6
      test/client.cpp
  5. BIN
      test/client.o
  6. 8
      test/server.cpp

@ -0,0 +1,13 @@
# A simple TCP socket library for C++
Object-oriented implemented library for easy creation and management of TCP sockets.
## Features
- Client aplication
- Server aplication
- Timeout connection
- SSL certificate

@ -14,6 +14,11 @@
using namespace std;
/**
* Server klasa za TCP/IP soket
* Instanca se incijalizira kada pokrećemo server
*/
class server {
public:
int sock;
@ -24,6 +29,11 @@ class server {
};
/**
* Klasa za konstrukciju i destrukciju SSL certifikata
* Pokreće se za server i client - (različiti konstruktori)
*/
class secure {
public:
SSL_CTX* fds;
@ -34,6 +44,11 @@ class secure {
};
/**
* Klasa za definiranje TCP soketa kod klijentskih aplikacija
*/
class client {
public:
int sock;
@ -47,6 +62,11 @@ class client {
};
/**
* Klasa za inicijalizaciju dolaznih veza
* Definira se na serverskom tipu aplikacija i predstavlja identifikator klijenta
*/
class comming {
public:
const server *srv;

@ -1,5 +1,9 @@
#include "../lib/tcp_socket.hpp"
/**
* Kontrustruktor varijable tipa server, prima port i limit za ograničenje liste klijenata na čekanju
*/
server::server (const ushort port, const uint limit) {
addr.sin_family = AF_INET;
@ -8,47 +12,59 @@ server::server (const ushort port, const uint limit) {
sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock <= 0) {
printf("[ERROR] Ne mogu otvoriti defenirani TCP/IP socket!");
throw "[ERROR] Unable to open TCP socket ";
}
int opt=1;
if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &opt, sizeof(opt))) {
printf("[ERROR] Ne mogu otvoriti defenirani TCP/IP socket!");
throw "[ERROR] Unable to set REUSEADDR or REUSEPORT on socket ";
}
if (bind(sock, (struct sockaddr *)&addr, sizeof(struct sockaddr_in)) < 0) {
printf("[ERROR] Ne mogu bindati defenirani TCP/IP socket!");
throw "[ERROR] Unable to bind socket ";
}
if (listen(sock, limit) < 0) {
printf("[ERROR] Ne mogu defenirani listen za TCP/IP socket!");
throw "[ERROR] It is not possible to set the allowed number of waiting clients ";
}
}
/**
* Destruktor varijable tipa server
*/
server::~server () {
if (sock<=0) {
printf ("[ERROR] Soket destruktor: već zatvoren soket!");
throw "[ERROR] The socket is already closed ";
}
else if (close(sock) != 0) {
printf ("[ERROR] Soket destruktor nije mogao zatvoriti soket!");
throw "[ERROR] Unable to close socket ";
}
}
/**
* Konstruktor varijable tipa secure za klijentske implementacije
*/
secure::secure() {
fds = SSL_CTX_new(SSLv23_client_method());
if (!fds) {
//throw "[ERROR] Creating SSL context ";
cout << endl << "[ERROR] Creating SSL context ";
throw "[ERROR] Creating SSL context ";
}
}
/**
* Konstruktor varijable tipa secure za serverske implementacije
*/
secure::secure(const string cert, const string priv) {
SSL_library_init();
@ -58,33 +74,40 @@ secure::secure(const string cert, const string priv) {
// Create an SSL context
fds = SSL_CTX_new(SSLv23_server_method());
if (!fds) {
// throw "[ERROR] Creating SSL context ";
cout << endl << "[ERROR] Creating SSL context ";
throw "[ERROR] Creating SSL context ";
}
// Load the server's certificate and private key files
if (SSL_CTX_use_certificate_file(fds, cert.c_str(), SSL_FILETYPE_PEM) <= 0) {
// throw "[ERROR] Loading certificate file.";
cout << endl << "[ERROR] Loading certificate file.";
throw "[ERROR] Loading certificate file ";
}
if (SSL_CTX_use_PrivateKey_file(fds, priv.c_str(), SSL_FILETYPE_PEM) <= 0) {
//throw "[ERROR] Loading private key file.";
cout << endl << "[ERROR] Loading private key file.";
throw "[ERROR] Loading private key file ";
}
}
/**
* Destruktor varijable tipa secure
*/
secure::~secure () {
SSL_CTX_free(fds);
}
/**
* Konstruktor varijable tipa client
* Prima adresu, port, i opcijonalno dozvoljeno vrijeme čekanja servera
* i deskriptor datoteke SSL certifikat za sigurne komunikacije
*/
client::client(const string address, const ushort port, const uint timeout, SSL_CTX* securefds) {
sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock < 0) {
printf("[ERROR] Ne mogu otvoriti TCP/IP socket!");
throw "[ERROR] Unable to open TCP socket ";
}
const string _address = isIPAddress(address) ? address : ipFromDomain(address);
@ -94,23 +117,21 @@ client::client(const string address, const ushort port, const uint timeout, SSL_
addr.sin_port = htons(port);
if (connect(sock, (struct sockaddr*)&addr, sizeof(struct sockaddr_in)) != 0) {
printf("[EROR] Ne mogu se povezati s poslužiteljem!");
throw "Unable to connect to server ";
}
struct timeval tv;
tv.tv_sec = 0; // za sad 2 sekunde timeout, harkodirano
tv.tv_sec = 0;
tv.tv_usec = timeout*1000;
if (setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(struct timeval))) {
printf ("[ERROR] 503 Ne mogu postaviti timeout!");
sock = -1;
throw "[ERROR] Unable to set timeout ";
}
if (securefds) {
ssl = SSL_new(securefds);
if (!ssl) {
//throw "[ERROR] Creating SSL object.";
cout << endl << "[ERROR] Creating SSL object.";
throw "[ERROR] Creating SSL object ";
}
SSL_set_fd(ssl, sock);
@ -118,13 +139,16 @@ client::client(const string address, const ushort port, const uint timeout, SSL_
// Perform the SSL handshake
if (SSL_connect(ssl) <= 0) {
SSL_free(ssl);
// throw "[ERROR] Performing SSL handshake.";
cout << endl << "[ERROR] Performing SSL handshake.";
throw "[ERROR] Performing SSL handshake ";
}
}
/**
* Destruktor varijable tipa client
*/
client::~client () {
if (ssl) {
@ -133,15 +157,21 @@ client::~client () {
}
if (sock <= 0) {
printf ("[ERROR] Soket destruktor: već zatvoren soket!");
throw "[ERROR] The socket is already closed ";
}
else if (close(sock) != 0) {
printf ("[ERROR] Soket destruktor nije mogao zatvoriti soket!");
throw "[ERROR] Unable to close socket ";
}
}
/**
* Metoda klase client za slanje podataka preko soketa
* Prima string koji će biti poslan
* Vraća logički statu poređenja psolanih karaktera i karaktera u stringu
*/
bool client::tell (const string msg) {
size_t sended = 0;
@ -154,6 +184,12 @@ bool client::tell (const string msg) {
return sended == msg.length();
}
/**
* Metoda klase client za primanje poruke preko soketa
* Prima dozvoljeni broj karaktera koji će primiti
* Vraća string primljene poruke
*/
string client::obey (size_t byte_limit) {
char res[byte_limit] = {0};
@ -167,6 +203,12 @@ string client::obey (size_t byte_limit) {
return (string) res;
}
/**
* Konstruktor varijable tipa commint
* Prima pokazivač na inicijaliziranu varijablu tipa, port,
* i opcijonalno dozvoljeno vrijeme čekanja servera i deskriptor datoteke
* SSL certifikat za sigurne komunikacije
*/
comming::comming(const server *_srv, const uint timeout, SSL_CTX* securefds) {
@ -174,7 +216,7 @@ comming::comming(const server *_srv, const uint timeout, SSL_CTX* securefds) {
socklen_t len = sizeof(struct sockaddr_in);
if ((conn = accept(srv->sock, (struct sockaddr *)&(srv->addr), (socklen_t*)&len)) < 0) {
printf("[ERROR] Ne mogu preuzeti vezu klijenta!");
throw "[ERROR] Unable to accept client connection ";
}
struct timeval tv;
@ -182,23 +224,20 @@ comming::comming(const server *_srv, const uint timeout, SSL_CTX* securefds) {
tv.tv_usec = 0;
if (setsockopt(conn, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(struct timeval))) {
printf("[ERROR] 503 Ne mogu postaviti timeout!");
conn = -1;
throw "[ERROR] Unable to set timeout ";
}
if (securefds) {
ssl = SSL_new(securefds);
if (!ssl) {
// throw "[ERROR] Creating SSL object.";
cout << endl << "[ERROR] Creating SSL object.";
throw "[ERROR] Creating SSL object ";
}
SSL_set_fd(ssl, conn);
// Perform SSL handshake
if (SSL_accept(ssl) <= 0) {
SSL_free(ssl);
// throw "[ERROR] Performing SSL handshake.";
cout << endl << "[ERROR] Performing SSL handshake.";
throw "[ERROR] Performing SSL handshake ";
}
}
@ -213,6 +252,10 @@ comming::comming(const server *_srv, const uint timeout, SSL_CTX* securefds) {
}
/**
* Destruktor varijable tipa comming
*/
comming::~comming() {
if (ssl) {
@ -221,14 +264,20 @@ comming::~comming() {
}
if (conn <= 0) {
printf ("[ERROR] Comming destruktor: već zatvoren soket!");
throw "[ERROR] The socket is already closed ";
}
else if (close(conn) != 0) {
printf ("[ERROR] Comming destruktor nije mogao zatvoriti soket!");
throw "[ERROR] Unable to close socket ";
}
}
/**
* Metoda klase comming za slanje podataka preko soketa
* Prima string koji će biti poslan
* Vraća logički statu poređenja psolanih karaktera i karaktera u stringu
*/
bool comming::tell (const string msg) {
ssize_t sended = 0;
if (ssl) {
@ -240,6 +289,13 @@ bool comming::tell (const string msg) {
return sended == msg.length();
}
/**
* Metoda klase comming za primanje poruke preko soketa
* Prima dozvoljeni broj karaktera koji će primiti
* Vraća string primljene poruke
*/
string comming::obey (size_t byte_limit) {
char res[byte_limit] = {0};

@ -6,12 +6,18 @@ using namespace std;
int main() {
try {
secure crypto;
client myserver("localhost", 5000, 500, crypto.fds);
string sends = "Hello world!";
cout << myserver.tell(sends) << " " << sends.length() << endl;
cout << myserver.obey();
}
catch (const string err) {
cout << err << endl;
}
return 0;
}

Binary file not shown.

@ -5,7 +5,7 @@
using namespace std;
int main() {
try{
cout << "init server " << endl;
server myserver(5000, 10);
cout << "init cert " << endl;
@ -31,7 +31,9 @@ int main() {
// }
// sleep(80);
}
catch(const string err) {
cout << err << endl;
}
return 0;
}
Loading…
Cancel
Save