From 98abf50da5f9144e4bd9bdb751cc0f20caabdae1 Mon Sep 17 00:00:00 2001 From: Aadhavan Srinivasan Date: Mon, 19 Feb 2024 21:28:07 -0500 Subject: [PATCH] Completely rewrote Server class, and split the class into header and implementation --- includes/server.hpp | 35 ++++++++++++----------- server.cpp | 69 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 88 insertions(+), 16 deletions(-) create mode 100644 server.cpp diff --git a/includes/server.hpp b/includes/server.hpp index 3a1d70b..b5a45a7 100644 --- a/includes/server.hpp +++ b/includes/server.hpp @@ -1,30 +1,33 @@ #ifndef _SERVER #define _SERVER #include "includes/sock.hpp" -#include "includes/exception_consts.hpp" -/* -Server class - Inherits from 'Sock' class - Defines a TCP/UDP server. -*/ +/* Server class - This class is used to create a TCP/UDP server. +It inherits from the 'Sock' class. */ class Server : public Sock { -private: - void create_socket() { - Sock::create_socket(); - this->sock_fd = create_local(this->ip_ver, this->protocol, this->address.data(), this->port, dest); - if (sock_fd < 0) { - if (sock_fd * -1 == ECONNREFUSED) { - throw EXCEPT_CONNREFUSED; - } - } - - } - public: + /* Constructors */ Server() {} Server(int ip_ver, char protocol, const char* address, int port) : Sock(ip_ver, protocol, address, port) {} + /* Destructor */ + ~Server(); + + /* Method to create socket - overrides (i.e. extends) method from parent class */ + void create_socket() override; + + /* FOR TCP ONLY - Wait for a peer to connect to this socket, and store the result in 'other_socket' */ + void wait_for_peer(); + + /* FOR TCP - Send data to the peer socket + FOR UDP - Send data to the client, from which data was received. + FOR UDP, this function MUST be called after recvAll() */ + void sendAll(std::string to_send); + + /* Receive data from peer socket */ + std::string recvAll(); }; #endif diff --git a/server.cpp b/server.cpp new file mode 100644 index 0000000..f14b804 --- /dev/null +++ b/server.cpp @@ -0,0 +1,69 @@ +#include +#include +#include "includes/sock.hpp" +#include "includes/server.hpp" +#include "includes/exception_consts.hpp" +#include "includes/easysock.hpp" + +/* Destructor - closes any open sockets */ +Server::~Server() { + close(this->other_socket); + close(this->sock_fd); +} + +/* Sends given data through the peer socket - This method is overriden from the +base method, because a different socket must be used. In the server's case, the +'peer' socket i.e. the socket returned after calling 'accept', must be used. */ + +void Server::sendAll(std::string to_send) { + Sock::sendAll(to_send, this->other_socket); +} + +/* Receives data from socket, and returns it. This function works differently +based on the Transport layer protocol used. For TCP, it calls the parent method +with the peer socket. As mentioned above, this is the socket returned after +calling the accept function. With UDP, there is no concept of a peer socket, and +so the regular server socket (the one created in create_socket() ) is used +instead. */ + +std::string Server::recvAll() { + if (this->protocol == 'T') { + return Sock::recvAll(this->other_socket); + } else { + return Sock::recvAll(this->sock_fd); + } +} + +/* FOR TCP ONLY - Waits for a peer to connect to the server socket. It stores +the return value of the accept() function i.e. the peer socket. This method does +nothing if your server socket is a UDP socket. If the accept function fails, the errno +is thrown as an exception. */ + +void Server::wait_for_peer() { + if (this->protocol == 'T') { + this->other_socket = accept(this->sock_fd, NULL, NULL); + if (this->other_socket < 0) { + throw errno; + } + } +} + +/* Creates a server socket. This method extends the parent method, and should be +called immediately after the constructor. If the socket is TCP, it also sets the +socket to listen for incoming connections. This function throws an exception if +the socket could not be created. The excpetion is an integer corresponding to the errno +of the failing function, and enables the caller to print a corresponding error message by +'catching' the thrown exception and using strerror(). */ + +void Server::create_socket() { + Sock::create_socket(); + this->sock_fd = create_local(this->ip_ver, this->protocol, this->address.data(), this->port, dest); + if (this->sock_fd < 0) { + throw (this->sock_fd * -1); + } + if (protocol == 'T') { + listen(sock_fd, 10); + } +} + +