Throwing exceptions
This commit is contained in:
parent
3bbfef613a
commit
31091dcbec
13
README.md
Normal file
13
README.md
Normal file
@ -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;
|
||||
}
|
BIN
test/client.o
BIN
test/client.o
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…
x
Reference in New Issue
Block a user