From f003947812a5d7fa8e58ea298340d503464213ec Mon Sep 17 00:00:00 2001 From: Guilherme Schmidt <101731542+Guilherme-L-Schmidt@users.noreply.github.com> Date: Sun, 30 Oct 2022 12:44:50 -0300 Subject: [PATCH 1/2] Added socket class --- src/classes/socket-handler/sockets.cpp | 286 +++++++++++++++++++++++++ src/classes/socket-handler/sockets.hpp | 52 +++++ 2 files changed, 338 insertions(+) create mode 100644 src/classes/socket-handler/sockets.cpp create mode 100644 src/classes/socket-handler/sockets.hpp diff --git a/src/classes/socket-handler/sockets.cpp b/src/classes/socket-handler/sockets.cpp new file mode 100644 index 0000000..273f5e4 --- /dev/null +++ b/src/classes/socket-handler/sockets.cpp @@ -0,0 +1,286 @@ +#include "sockets.hpp" + +int SocketHandler::connection_socket; + +/** Starts main daemon's socket + * @return 0 on succes, -1 on failure + */ +int SocketHandler::start() { + unlink(SOCKET_NAME); + + struct sockaddr_un address; + memset(&address, 0, sizeof(address)); + + // Creates a local main socket + connection_socket = socket(AF_UNIX, SOCK_SEQPACKET, 0); + if (connection_socket == -1) { + perror("socket"); + return -1; + } + + // Binds socket to defined address + address.sun_family = AF_UNIX; + strncpy(address.sun_path, SOCKET_NAME, sizeof(address.sun_path) - 1); + if (bind(connection_socket, (const struct sockaddr *) &address, sizeof(address)) == -1) { + perror("bind"); + return -1; + } + + // Prepares for accepting connections + if (listen(connection_socket, 20) == -1) { + perror("listen"); + return -1; + } + + return 0; +} + +/** Starts client sockets + * @param name client's name + * @return 0 on success, -1 on failure + */ +int SocketHandler::openSocket(std::string name) { + struct sockaddr_un address; + memset(&address, 0, sizeof(address)); + + // Creates local socket + connection_socket = socket(AF_UNIX, SOCK_SEQPACKET, 0); + if (connection_socket == -1) { + perror("socket"); + return -1; + } + + // Connects to main_daemon's socket adress + address.sun_family = AF_UNIX; + strncpy(address.sun_path, SOCKET_NAME, sizeof(address.sun_path) - 1); + + if (connect(connection_socket, (const struct sockaddr *) &address, sizeof(address)) == -1) { + perror("The server is down"); + return -1; + } + + // Sends socket information to main + write(connection_socket, name.c_str(), name.length()); + + // Confirmation + char buffer[5] = "null"; + while(strcmp(buffer, "rcvd") != 0) { + read(connection_socket, buffer, 5); + } + return 0; +} + +/** Client main listening function + * @param com Message pointer to receive the incoming message + * @param dropout_time struct in {seconds, milisseconds} that defines time until dropping the listening function, when no messages are received + * @return 1 on success, 0 if server is down, -1 on local failure + */ +int SocketHandler::listenClient(SocketHandler::Message* com, struct timeval dropout_time) { + // Puts all sockets on list + fd_set fd_reads; + FD_ZERO(&fd_reads); + FD_SET(connection_socket, &fd_reads); + + // Checks wich sockets can be read + ssize_t activity = select(connection_socket + 1, &fd_reads, NULL, NULL, &dropout_time); + if ((activity < 0) && (errno!=EINTR)) { + printf("select error"); + return -1; + } + + // Reads message, if present + if (FD_ISSET(connection_socket, &fd_reads)) { + int temp; + char buffer[STD_SIZE]; + + if((temp = read(connection_socket, buffer, STD_SIZE)) == -1) { + perror("read"); + write(connection_socket, "-1", 3); + return -1; + } + else if (temp == 0) { + close(connection_socket); + return 0; + } + else { + buffer[temp] = '\0'; + + // Returns message + *com = SocketHandler::strToMsg(buffer); + } + } + + return 1; +} + +/** Server listening function + * @param client_sockets int array with all connected sockets + * @param connection_list string array with all socket names + * @param size size of the given arrays + * @param server_com Message pointer to receive incoming server messages + * @return 1 on success, 0 on receiving server message, -1 on critical failure + */ +int SocketHandler::listenServer(int* client_sockets, std::string* connection_list, int size, SocketHandler::Message* server_com, struct timeval dropout_time) { + // Puts all sockets on list + int max_fd = connection_socket; + fd_set fd_reads; + FD_ZERO(&fd_reads); + FD_SET(connection_socket, &fd_reads); + for (int i = 0; i < size; i++) { + if (client_sockets[i] != 0) { + FD_SET(client_sockets[i], &fd_reads); + if (client_sockets[i] > max_fd) { + max_fd = client_sockets[i]; + } + } + } + + struct timeval time = {1,0}; + // Checks wich sockets can be read + ssize_t activity = select(max_fd + 1, &fd_reads, NULL, NULL, &time); + if ((activity < 0) && (errno!=EINTR)) { + printf("select error"); + return -1; + } + + // If main socket can be read, accepts new connections + if (FD_ISSET(connection_socket, &fd_reads)) { + int temp; + // Accepts + if ((temp = accept(connection_socket, NULL, NULL)) == -1) { + perror("accept"); + } + + // Gets connected socket's identity + char buffer[STD_SIZE]; + read(temp, buffer, STD_SIZE); + + for (int i = 0; i < size; i++) { + if (strcmp(buffer, connection_list[i].c_str()) == 0) { + client_sockets[i] = temp; + printf("Stored new connection\n"); + } + } + + write(temp, "rcvd", 5); + } + + // Transfers messages between children + for (int i = 0; i < size; i++) { + if (FD_ISSET(client_sockets[i], &fd_reads)) { + int signal; + char buffer[STD_SIZE]; + if ((signal = read(client_sockets[i], buffer, STD_SIZE)) == -1) { + perror("read"); + } + // Socket closing signal + else if (signal == 0) { + close(client_sockets[i]); + client_sockets[i] = 0; + // Can include code to inform main of the event + } + // Transfers message or receives it + else { + buffer[signal] = '\0'; + SocketHandler::Message com = strToMsg(buffer); + + if (std::stoi(com.send_to) < 0 || std::stoi(com.send_to) > size) { + write(client_sockets[std::stoi(com.sent_from)-1], "-1", 3); + } + else if (std::stoi(com.send_to) == 0) { + *server_com = com; + write(client_sockets[std::stoi(com.sent_from)-1], "1", 2); + return 0; + } + else { + int temp; + temp = transfer(com, client_sockets, size); + char msg[3]; + sprintf(msg, "%d", temp); + write(client_sockets[std::stoi(com.sent_from)-1], msg, 3); + } + } + } + } + return 1; +} + +/** Send message from client to server + * @param socket socket to be sent the message + * @param com Message to be sent + * @return 1 on success, 0 if destination does not exist, -1 on failure + */ +int SocketHandler::sendMessage(int socket, SocketHandler::Message com) { + std::string men = com.send_to + "," + com.sent_from + "," + com.message; + + if (write(socket, men.c_str(), men.length()) == -1) { + perror("message not sent"); + return -1; + } + + char buffer[3]; + read(socket, buffer, 3); + buffer[2] = '\0'; + + if (atoi(buffer) == -1) { + printf("message not sent\n"); + } + else if (atoi(buffer) == 0) { + printf("destination unavailable\n"); + } + + return atoi(buffer); +} + +/** Transfers messages between clients + * @param com Message to be transferes + * @param client_sockets int array with al connected sockets + * @param size size of the client array + * @return 1 on success, 0 if destination cannot be found, -1 on failure + */ +// implement error if client adress is 0 +int SocketHandler::transfer(SocketHandler::Message com, int* client_sockets, int size) { + std::string men = com.send_to + "," + com.sent_from + "," + com.message; + + if (client_sockets[std::stoi(com.send_to)-1] == 0) { + return 0; + } + if (write(client_sockets[std::stoi(com.send_to)-1], men.c_str(), men.length()) == -1) { + perror("message not sent"); + return -1; + } + + return 1; +} + +/** Converts strings to Message format + * @param com string to be converted + * @return returns Message recovered from string + */ +SocketHandler::Message SocketHandler::strToMsg(char* com) { + std::string cut[3]; + int i = 0, j = 0; + while (com[i] != '\0' && j < 3) { + if (com[i] != ',') { + cut[j] += com[i]; + } + else { + j++; + } + i++; + } + + SocketHandler::Message mes {cut[0], cut[1], cut[2]}; + + return mes; +} + +/** Closes local socket and unlinks its name + * @param dis_socket socket to be disconnected + */ +void SocketHandler::closeSocket(int dis_socket) { + struct sockaddr_un name; + getpeername(dis_socket, (struct sockaddr *) &name, (socklen_t *) sizeof(name)); + close(dis_socket); + unlink(name.sun_path); +} diff --git a/src/classes/socket-handler/sockets.hpp b/src/classes/socket-handler/sockets.hpp new file mode 100644 index 0000000..aa418e5 --- /dev/null +++ b/src/classes/socket-handler/sockets.hpp @@ -0,0 +1,52 @@ +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define SOCKET_NAME "/tmp/server.socket" +#define STD_SIZE 128 + +class SocketHandler { + public: + struct Message { + std::string send_to; + std::string sent_from; + std::string message; + + Message() = default; + + Message(std::string send, std::string sent, std::string mess) + : send_to { std::move(send) } + , sent_from { std::move(sent) } + , message { std::move(mess) } + {}; + }; + + static int connection_socket; + + public: + static int start(); + + static int openSocket(std::string name); + + static int listenClient(SocketHandler::Message* com, struct timeval dropout_time); + + static int listenServer(int* sockets, std::string* connection_list, int size, SocketHandler::Message* server_com, struct timeval dropout_time); + + static int sendMessage(int socket, Message com); + + static void closeSocket(int dis_socket); + + private: + + static int transfer(Message com, int* sockets, int size); + + static Message strToMsg(char* com); +}; \ No newline at end of file From d834f96e7183f8a695cd3e2aad090e8abb91cdf5 Mon Sep 17 00:00:00 2001 From: Dynamic Readme Date: Sun, 30 Oct 2022 15:45:10 +0000 Subject: [PATCH 2/2] =?UTF-8?q?=F0=9F=92=AC=20-=20File=20Rebuilt=20-=20Git?= =?UTF-8?q?hub=20Action=20Runner=20:=20${GITHUB=5FRUN=5FNUMBER}?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index 7725d8e..26f9bd0 100644 --- a/README.md +++ b/README.md @@ -8,26 +8,26 @@ - - + + - - + + - - + + - - + + - - + + - - + + - - + +