commit 072c0e141cd5e6e6a55e0e63db21e1b1c6b3472f Author: marcelb Date: Sun May 21 08:54:11 2023 +0200 Tested diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..1507357 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,5 @@ +{ + "files.associations": { + "functional": "cpp" + } +} \ No newline at end of file diff --git a/lib/ip.hpp b/lib/ip.hpp new file mode 100644 index 0000000..81b07de --- /dev/null +++ b/lib/ip.hpp @@ -0,0 +1,20 @@ +#ifndef _IP_ +#define _IP_ + +#include +#include +#include +#include +#include +#include + +using namespace std; + +bool isIPAddress(const string address); +bool isIPv4 (const string address); +bool isIPv6 (const string address); +string ipFromDomain(const string domain); + + + +#endif \ No newline at end of file diff --git a/lib/tcp_socket.hpp b/lib/tcp_socket.hpp new file mode 100644 index 0000000..b702bf6 --- /dev/null +++ b/lib/tcp_socket.hpp @@ -0,0 +1,56 @@ +#ifndef TCP_SCK +#define TCP_SCK + +#include +#include +#include +#include +#include +#include + +#include "ip.hpp" + +using namespace std; + +class server { + public: + int sock; + struct sockaddr_in addr; + + server (const ushort port, const uint limit = 1000); + ~server (); + + +}; + + +class client { + public: + int sock; + struct sockaddr_in addr; + + client (const string address, const ushort port); + ~client (); + bool tell (const string msg); + string obey (size_t byte_limit = 1024); +}; + + +class comming { + public: + const server *srv; + int conn; + string ipv4; + string ipv6; + + comming(const server *_srv, const uint timeout); + ~comming(); + bool tell (const string msg); + string obey (size_t byte_limit = 1024); + +}; + + + + +#endif \ No newline at end of file diff --git a/src/ip.cpp b/src/ip.cpp new file mode 100644 index 0000000..658ba77 --- /dev/null +++ b/src/ip.cpp @@ -0,0 +1,35 @@ +#include "../lib/ip.hpp" + + +bool isIPAddress(const string address) { + char buf[16]; + return isIPv4(address) || isIPv6(address) ; +} + +bool isIPv4 (const string address) { + char buf[16]; + return inet_pton(AF_INET, address.c_str(), buf); +} + +bool isIPv6 (const string address) { + char buf[16]; + return inet_pton(AF_INET6, address.c_str(), buf); +} + +string ipFromDomain(const string domain) { + struct hostent *host_name; + struct in_addr **ipaddress; + int i; + char ip_address[INET6_ADDRSTRLEN]; + + if((host_name = gethostbyname(domain.c_str())) == NULL) { + printf ("[ERROR] IP Address Not Found from domain!"); + } + + ipaddress = (struct in_addr **) host_name->h_addr_list; + for(i = 0; ipaddress[i] != NULL; i++) { + strcpy(ip_address, inet_ntoa(*ipaddress[i])); + } + + return (string) ip_address; +} \ No newline at end of file diff --git a/src/tcp_socket.cpp b/src/tcp_socket.cpp new file mode 100644 index 0000000..ab2898f --- /dev/null +++ b/src/tcp_socket.cpp @@ -0,0 +1,128 @@ +#include "../lib/tcp_socket.hpp" + +server::server (const ushort port, const uint limit) { + + addr.sin_family = AF_INET; + addr.sin_addr.s_addr = INADDR_ANY; + addr.sin_port = htons(port); + + sock = socket(AF_INET, SOCK_STREAM, 0); + if (sock <= 0) { + printf("[ERROR] Ne mogu otvoriti defenirani TCP/IP socket!"); + } + + int opt=1; + if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt))) { + printf("[ERROR] Ne mogu otvoriti defenirani TCP/IP socket!"); + } + printf("[EVENT] Otvoren defenirani TCP/IP socket."); + + if (bind(sock, (struct sockaddr *)&addr, sizeof(struct sockaddr_in)) < 0) { + printf("[ERROR] Ne mogu bindati defenirani TCP/IP socket!"); + } + + if (listen(sock, limit) < 0) { + printf("[ERROR] Ne mogu defenirani listen za TCP/IP socket!"); + } + +} + + +server::~server () { + + if (sock<0) { + printf ("[ERROR] Soket destruktor: već zatvoren soket!"); + } + + else if (!close(sock)) { + printf ("[ERROR] Soket destruktor nije mogao zatvoriti soket!"); + } + +} + + +client::client(const string address, const ushort port) { + + sock = socket(AF_INET, SOCK_STREAM, 0); + if (sock < 0) { + printf("[ERROR] Ne mogu otvoriti TCP/IP socket!"); + } + + const string _address = isIPAddress(address) ? address : ipFromDomain(address); + + addr.sin_family = AF_INET; + addr.sin_addr.s_addr = inet_addr(_address.c_str()); + 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!"); + } + +} + + +client::~client () { + + if (sock <= 0) { + printf ("[ERROR] Soket destruktor: već zatvoren soket!"); + } + + else if (close(sock) != 0) { + printf ("[ERROR] Soket destruktor nije mogao zatvoriti soket!"); + } + +} + + +bool client::tell (const string msg) { + ssize_t sended = send(sock, msg.c_str(), msg.length(),0); + return sended == msg.length(); +} + +string client::obey (size_t byte_limit) { + char res[byte_limit] = {0}; + ssize_t n = read ( sock , res, byte_limit); + return (string) res; +} + + + +comming::comming(const server *_srv, const uint timeout) { + srv = _srv; + 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!"); + } + + char ipv4_buff[INET_ADDRSTRLEN]; + char ipv6_buff[INET6_ADDRSTRLEN]; + + inet_ntop(AF_INET, &(srv->addr.sin_addr), ipv4_buff, INET_ADDRSTRLEN); + ipv4 = ipv4_buff; + inet_ntop(AF_INET6, &(srv->addr.sin_addr), ipv6_buff, INET6_ADDRSTRLEN); + ipv6 = ipv6_buff; + + +} + +comming::~comming() { + if (conn <= 0) { + printf ("[ERROR] Comming destruktor: već zatvoren soket!"); + } + + else if (close(conn) != 0) { + printf ("[ERROR] Comming destruktor nije mogao zatvoriti soket!"); + } +} + +bool comming::tell (const string msg) { + ssize_t sended = send(conn, msg.c_str(), msg.length(),0); + return sended == msg.length(); +} + +string comming::obey (size_t byte_limit) { + char res[byte_limit] = {0}; + ssize_t n = read ( conn , res, byte_limit); + return (string) res; +} \ No newline at end of file diff --git a/test/client.cpp b/test/client.cpp new file mode 100644 index 0000000..083c994 --- /dev/null +++ b/test/client.cpp @@ -0,0 +1,15 @@ +#include + +#include "../lib/tcp_socket.hpp" + +using namespace std; + +int main() { + + client myserver("localhost", 5000); + string sends = "Hello wld!"; + cout << myserver.tell(sends) << " " << sends.length() << endl; + cout << myserver.obey(); + + return 0; +} \ No newline at end of file diff --git a/test/client.o b/test/client.o new file mode 100755 index 0000000..9254249 Binary files /dev/null and b/test/client.o differ diff --git a/test/compile-client.sh b/test/compile-client.sh new file mode 100644 index 0000000..c0b31c0 --- /dev/null +++ b/test/compile-client.sh @@ -0,0 +1 @@ +g++ client.cpp ../src/* -o client.o \ No newline at end of file diff --git a/test/compile-server.sh b/test/compile-server.sh new file mode 100644 index 0000000..e6bb7c9 --- /dev/null +++ b/test/compile-server.sh @@ -0,0 +1 @@ +g++ server.cpp ../src/* -o server.o \ No newline at end of file diff --git a/test/server.cpp b/test/server.cpp new file mode 100644 index 0000000..c0139ca --- /dev/null +++ b/test/server.cpp @@ -0,0 +1,27 @@ +#include + +#include "../lib/tcp_socket.hpp" + +using namespace std; + +int main() { + + server myserver(5000, 10); + comming myclient(&myserver, 1000); + + string fromclient = myclient.obey(); + myclient.tell(fromclient); + myclient.~comming(); + + while (true) { + comming myclient(&myserver, 1000); + string fromclient = myclient.obey(); + cout << fromclient << " " << myclient.conn << endl; + cout << "Poslano: " << myclient.tell(fromclient) << "Veličin: " << fromclient.length() << endl; + // myclient.~comming(); + cout << "IPv4 " << myclient.ipv4 << " ipv6 " << myclient.ipv6; + } + + + return 0; +} \ No newline at end of file diff --git a/test/server.o b/test/server.o new file mode 100755 index 0000000..2a5703a Binary files /dev/null and b/test/server.o differ