From bf00253b28757e4aa77a99daa84531151d8f5a72 Mon Sep 17 00:00:00 2001 From: Namonay Date: Mon, 22 Jan 2024 01:40:02 +0100 Subject: [PATCH] yipiiii --- Makefile | 3 +- includes/client.hpp | 15 ++++++--- includes/server.hpp | 13 +++++--- srcs/client.cpp | 6 ++-- srcs/server.cpp | 79 +++++++++++++++++++++++++++++++++++++++------ 5 files changed, 93 insertions(+), 23 deletions(-) diff --git a/Makefile b/Makefile index 9f1c8f9..7034339 100644 --- a/Makefile +++ b/Makefile @@ -6,7 +6,7 @@ # By: vvaas +#+ +:+ +#+ # # +#+#+#+#+#+ +#+ # # Created: 2023/08/09 15:08:49 by vavaas #+# #+# # -# Updated: 2024/01/21 17:23:26 by vvaas ### ########.fr # +# Updated: 2024/01/21 19:57:45 by vvaas ### ########.fr # # # #******************************************************************************# @@ -30,7 +30,6 @@ ifeq ($(FLAGS), true) CXXFLAGS += -Wall -Wextra -Werror endif - DEBUG ?= false MODE = "release" diff --git a/includes/client.hpp b/includes/client.hpp index e9c4fd6..88418e9 100644 --- a/includes/client.hpp +++ b/includes/client.hpp @@ -6,24 +6,31 @@ /* By: vvaas +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/01/21 10:33:17 by maldavid #+# #+# */ -/* Updated: 2024/01/21 16:32:05 by vvaas ### ########.fr */ +/* Updated: 2024/01/22 01:29:55 by vvaas ### ########.fr */ /* */ /******************************************************************************/ #ifndef __CLIENT__ #define __CLIENT__ - +#include +#include +#include namespace irc { class Client { public: - Client(int fd); - + Client(int fd, sockaddr_in sock, int id); + inline int get_fd(void) { return (_fd); } + inline void set_fd(int new_fd) { _fd = new_fd; } + inline sockaddr_in get_sockaddr(void) { return (_s_data); } + inline std::string get_string_id(void) { std::stringstream out; out << _id; return (out.str()); } ~Client(); private: + sockaddr_in _s_data; int _fd; + int _id; }; } diff --git a/includes/server.hpp b/includes/server.hpp index e2bd3df..5f24321 100644 --- a/includes/server.hpp +++ b/includes/server.hpp @@ -6,7 +6,7 @@ /* By: vvaas +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/01/21 09:12:28 by maldavid #+# #+# */ -/* Updated: 2024/01/21 17:18:17 by vvaas ### ########.fr */ +/* Updated: 2024/01/22 01:14:42 by vvaas ### ########.fr */ /* */ /******************************************************************************/ @@ -17,6 +17,7 @@ #include #include #include +#include #define MAX_USERS 20 namespace irc @@ -28,18 +29,22 @@ namespace irc ~Server(); inline unsigned long get_port(void) { return (htons(_port)); } - private: void init_socket(void); - void wait(void); + void init_socket_data(void); + void init_signal(void); + void wait(void); + void add_client(int fd); + + void handle_input(void); private: sockaddr_in _s_data; socklen_t _s_len; fd_set _fd_set; std::vector _channels; - std::vector > _client; + std::vector _client; const std::string _password; const std::string _ip; const int _port; diff --git a/srcs/client.cpp b/srcs/client.cpp index 6689993..4c3ec04 100644 --- a/srcs/client.cpp +++ b/srcs/client.cpp @@ -6,7 +6,7 @@ /* By: vvaas +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/01/21 10:35:52 by maldavid #+# #+# */ -/* Updated: 2024/01/21 16:32:12 by vvaas ### ########.fr */ +/* Updated: 2024/01/22 01:27:30 by vvaas ### ########.fr */ /* */ /******************************************************************************/ @@ -14,9 +14,9 @@ namespace irc { - Client::Client(int fd) : _fd(fd) + Client::Client(int fd, sockaddr_in sock, int id) : _s_data(sock), _fd(fd), _id(id) { - + } Client::~Client() {} diff --git a/srcs/server.cpp b/srcs/server.cpp index 4bede37..c2cbb16 100644 --- a/srcs/server.cpp +++ b/srcs/server.cpp @@ -6,7 +6,7 @@ /* By: vvaas +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/01/21 09:31:17 by maldavid #+# #+# */ -/* Updated: 2024/01/21 17:31:15 by vvaas ### ########.fr */ +/* Updated: 2024/01/22 01:39:29 by vvaas ### ########.fr */ /* */ /******************************************************************************/ @@ -15,6 +15,10 @@ #include #include #include +#include +#include +#include +#include /** Commands to handle * NICK @@ -39,31 +43,86 @@ namespace irc init_socket(); wait(); } - void Server::init_socket(void) + + void Server::init_socket_data(void) { _s_data.sin_family = AF_INET; _s_data.sin_addr.s_addr = INADDR_ANY; _s_data.sin_port = htons(_port); _main_socket = socket(AF_INET, SOCK_STREAM, 0); // AF_INET == IPv4, SOCK_STREAM == TCP if (_main_socket < 0) - irc::logs::report(irc::log_fatal_error, "socket error"); - std::cout << "Socket creating succesful" << std::endl; - if (bind(_main_socket, (struct sockaddr *)&_s_data, sizeof(_s_data)) != 0) - irc::logs::report(irc::log_fatal_error, "bind error"); - std::cout << "bind succesful, starting listen loop" << std::endl; - if (listen(_main_socket, MAX_USERS) != 0) - irc::logs::report(irc::log_fatal_error, "listen error"); - std::cout << "listen queue created succesful" << std::endl; + logs::report(log_fatal_error, "socket error"); + logs::report(log_message, "socket succesfully started"); + } + + void Server::init_socket(void) + { + int opt = 0; + + init_socket_data(); + if (setsockopt(_main_socket, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) < 0) // SOL_SOCKET : modify socket only, SO_REUSEADDR : Reusable after program ends + logs::report(log_fatal_error, "setsockopt() error (tout a pete)"); + if (bind(_main_socket, (struct sockaddr *)&_s_data, sizeof(_s_data)) != 0) // Bind _main_socket to localhost + logs::report(log_fatal_error, "bind error"); + logs::report(log_message, "bind successful, starting listen loop"); + if (listen(_main_socket, MAX_USERS) != 0) // init the listen with MAX_USERS + logs::report(log_fatal_error, "listen error"); + logs::report(log_message, "listen queue created successfully"); + logs::report(log_message, "Server is running"); + } + + void Server::handle_input(void) + { + char buffer[1024] = {0}; + + for (std::vector::iterator it = _client.begin(); it != _client.end(); it++) + { + if (!FD_ISSET(it->get_fd(), &_fd_set)) + continue ; + while (recv(it->get_fd(), buffer, 10, 0) > 0) // read() but for socket fd + { + std::cout << AnsiColor::cyan << "[User " << it->get_string_id() << "] : " << AnsiColor::reset << buffer << std::flush; + memset(buffer, 0, sizeof(buffer)); // clear the buffer to avoid trash remaining + } + if (recv(it->get_fd(), buffer, 10, 0) == 0) // recv return 0 if an user disconnect + { + std::cout << AnsiColor::cyan << "[User " << it->get_string_id() << "] : " << AnsiColor::reset << "Disconnected" << std::endl; + it = _client.erase(it) - 1; // magic bitch + } + } } void Server::wait(void) { + int tmp; + int fd = 0; + int i = 0; + socklen_t len = sizeof(sockaddr_in); + while (_active) { FD_ZERO(&_fd_set); FD_SET(_main_socket, &_fd_set); + for (std::vector::iterator it = _client.begin(); it != _client.end(); it++) + FD_SET(it->get_fd(), &_fd_set); + tmp = select(MAX_USERS, &_fd_set, NULL, NULL, NULL); // SELECT blocks till a connection or message is received, and let only those in _fd_set + if (tmp < 0) + logs::report(log_fatal_error, "select fd error"); + if (FD_ISSET(_main_socket, &_fd_set)) // if it's a new connection + { + sockaddr_in cli_sock; + fd = accept(_main_socket, (sockaddr *)&cli_sock, &len); // adds the new connection + if (fd < 0) + logs::report(log_fatal_error, "accept() error"); + if (fcntl(fd, F_SETFL, O_NONBLOCK) < 0) + logs::report(log_fatal_error, "fcntl() error"); + _client.push_back(Client(fd, cli_sock, i++)); // put the client into the vector used in handle_input + std::cout << AnsiColor::cyan << "[User " << _client.back().get_string_id() << "] : " << AnsiColor::reset << "Connected" << std::endl; + } + handle_input(); } } + Server::~Server() { if (_main_socket > 0)