Skip to content

Commit

Permalink
server state skeleton done
Browse files Browse the repository at this point in the history
  • Loading branch information
simaosanguinho committed Dec 8, 2023
1 parent 2ad0a19 commit 9d0156b
Show file tree
Hide file tree
Showing 8 changed files with 208 additions and 3 deletions.
Binary file added 2023_2024_proj_auto_avaliacao.pdf
Binary file not shown.
1 change: 1 addition & 0 deletions src/client/user.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include <sys/types.h>
#include <unistd.h>

// flag to indicate whether the client is terminating
extern bool is_exiting;

int main(int argc, char *argv[]) {
Expand Down
29 changes: 28 additions & 1 deletion src/server/server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,34 @@
#include <iostream>
#include <thread>

int main() { return 0; }
// flag to indicate whether the server is terminating
extern bool is_exiting;

int main(int argc, char *argv[]) {

try {
ServerConfig config(argc, argv);
if (config.help) {
config.printHelp(std::cout);
return EXIT_SUCCESS;
}

setup_custom_signal_handlers();

// TODO: print verbose mode activated if so

while (!is_exiting) {
}
} catch (...) {
std::cerr << "An error has ocurred while running the application. "
"Shutting down..."
<< std::endl;

return EXIT_FAILURE;
}

return 0;
}

ServerConfig::ServerConfig(int argc, char *argv[]) {
programPath = argv[0];
Expand Down
3 changes: 3 additions & 0 deletions src/server/server.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
#include "../utils/constants.hpp"
#include "../utils/utils.hpp"

#include "../utils/protocol.hpp"

class ServerConfig {
public:
char *programPath;
Expand All @@ -18,4 +20,5 @@ class ServerConfig {
void printHelp(std::ostream &stream);
};

void waitForUdpPacket(UdpPacket &packet);
#endif
85 changes: 85 additions & 0 deletions src/server/server_state.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
#include "server_state.hpp"

#include <cstring>
#include <filesystem>
#include <fstream>
#include <iostream>
#include <unistd.h>

void AuctionServerState::resolveServerAddress(std::string &port) {
struct addrinfo hints;
int addr_res;
const char *port_str = port.c_str();
// Get the UDP address
memset(&hints, 0, sizeof hints);
hints.ai_family = AF_INET; // IPv4
hints.ai_socktype = SOCK_DGRAM; // UDP socket
hints.ai_flags = AI_PASSIVE; // Listen on 0.0.0.0
if ((addr_res = getaddrinfo(NULL, port_str, &hints, &this->serverUdpAddr)) !=
0) {
throw FatalError(std::string("Failed to get address for UDP connection: ") +
gai_strerror(addr_res));
}
if (bind(this->udpSocketFD, this->serverUdpAddr->ai_addr,
this->serverUdpAddr->ai_addrlen)) {
throw FatalError("Failed to bind UDP address", errno);
}

// Get the TCP address
memset(&hints, 0, sizeof hints);
hints.ai_family = AF_INET; // IPv4
hints.ai_socktype = SOCK_STREAM; // TCP socket
hints.ai_flags = AI_PASSIVE; // Listen on 0.0.0.0
if ((addr_res = getaddrinfo(NULL, port.c_str(), &hints,
&this->serverTcpAddr)) != 0) {
throw FatalError(std::string("Failed to get address for TCP connection: ") +
gai_strerror(addr_res));
}

if (bind(this->tcpSocketFD, this->serverTcpAddr->ai_addr,
this->serverTcpAddr->ai_addrlen)) {
throw FatalError("Failed to bind TCP address", errno);
}

std::cout << "Listening for connections on port " << port << std::endl;
}

void AuctionServerState::setupUdpSocket() {
// Create a UDP socket
if ((this->udpSocketFD = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
throw FatalError("Failed to create a UDP socket", errno);
}
struct timeval timeout;
timeout.tv_sec = SERVER_TIMEOUT;
timeout.tv_usec = 0;
if (setsockopt(this->udpSocketFD, SOL_SOCKET, SO_RCVTIMEO, &timeout,
sizeof(timeout)) < 0) {
throw FatalError("Failed to set UDP read timeout socket option", errno);
}
}

void AuctionServerState::setupTcpSocket() {
// Create a TCP socket
if ((this->tcpSocketFD = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
throw FatalError("Failed to create a TCP socket", errno);
}
const int enable = 1;
if (setsockopt(this->tcpSocketFD, SOL_SOCKET, SO_REUSEADDR, &enable,
sizeof(int)) < 0) {
throw FatalError("Failed to set TCP reuse address socket option", errno);
}
struct timeval timeoutRead;
timeoutRead.tv_sec = SERVER_TIMEOUT;
timeoutRead.tv_usec = 0;
if (setsockopt(this->tcpSocketFD, SOL_SOCKET, SO_RCVTIMEO, &timeoutRead,
sizeof(timeoutRead)) < 0) {
throw FatalError("Failed to set TCP read timeout socket option", errno);
}
struct timeval timeoutWrite;
timeoutWrite.tv_sec = TCP_WRITE_TIMEOUT_SECONDS;
timeoutWrite.tv_usec = 0;
if (setsockopt(this->tcpSocketFD, SOL_SOCKET, SO_SNDTIMEO, &timeoutWrite,
sizeof(timeoutWrite)) < 0) {
throw FatalError("Failed to set TCP write timeout socket option", errno);
}
}
87 changes: 87 additions & 0 deletions src/server/server_state.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
#ifndef SERVER_STATE_H
#define SERVER_STATE_H

#include <netdb.h>

#include <filesystem>
#include <iostream>
#include <optional>
#include <sstream>
#include <unordered_map>

#include "../utils/constants.hpp"
#include "../utils/utils.hpp"

class AuctionServerState;

/**
* @class SocketAddress
*
* @brief Represents a socket address.
*/
class SocketAddress {
public:
int socket;
struct sockaddr_in addr;
socklen_t size;
};

typedef void (*UdpPacketHandler)(std::stringstream &, SocketAddress &,
AuctionServerState &);
typedef void (*TcpPacketHandler)(int fd, AuctionServerState &);

/**
* @class ServerState
*
* @brief Represents the state of the server.
*
* The ServerState class encapsulates the state of the server, including the
* server's port, word file path, and a map of usernames to passwords.
*/
class AuctionServerState {
int udpSocketFD = -1;
int tcpSocketFD = -1;
struct addrinfo *serverUdpAddr = NULL;
struct addrinfo *serverTcpAddr = NULL;

// Maps the command string to the handler type
std::unordered_map<std::string, UdpPacketHandler> UdpPacketHandlers;
std::unordered_map<std::string, TcpPacketHandler> TcpPacketHandlers;

public:
/**
* @brief Sets up a UDP socket.
*
*/
void setupUdpSocket();

/**
* @brief Sets up a TCP socket.
*
*/
void setupTcpSocket();

/**
* @brief Resolves the incoming address.
*
* @param port The port of the server.
*/
void resolveServerAddress(std::string &port);

/**
* @brief Registers all server handlers
*/
void registerHandles();

/**
* @brief Registers a UDP packet handler with the server.
*/
void registerUdpPacketHandler();

/**
* @brief Registers a TCP packet handler with the server.
*/
void registerTcpPacketHandler();
};

#endif
4 changes: 3 additions & 1 deletion src/utils/constants.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@

#define TCP_WRITE_TIMEOUT_SECONDS 20
#define TCP_READ_TIMEOUT_SECONDS 20
#define PROGRESS_BAR_STEP_SIZE 10
#define PROGRESS_BAR_STEP_SIZE 10 // not needed

#define SERVER_TIMEOUT 3

#endif
2 changes: 1 addition & 1 deletion src/utils/utils.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#include "utils.hpp"

// Flag to indicate whether the application is shutting down
// Flag to indicate whether the application is terminating
bool is_exiting = false;

void validate_port_number(const std::string &port_number) {
Expand Down

0 comments on commit 9d0156b

Please sign in to comment.