This commit is contained in:
Ladebeze66 2024-05-10 15:07:49 +02:00
parent a1a7eb5b57
commit be09476005
12 changed files with 167 additions and 46 deletions

52
ft_irc/.vscode/settings.json vendored Normal file
View File

@ -0,0 +1,52 @@
{
"files.associations": {
"array": "cpp",
"atomic": "cpp",
"bit": "cpp",
"*.tcc": "cpp",
"cctype": "cpp",
"clocale": "cpp",
"cmath": "cpp",
"compare": "cpp",
"concepts": "cpp",
"cstdarg": "cpp",
"cstddef": "cpp",
"cstdint": "cpp",
"cstdio": "cpp",
"cstdlib": "cpp",
"cstring": "cpp",
"ctime": "cpp",
"cwchar": "cpp",
"cwctype": "cpp",
"deque": "cpp",
"map": "cpp",
"string": "cpp",
"unordered_map": "cpp",
"vector": "cpp",
"exception": "cpp",
"algorithm": "cpp",
"functional": "cpp",
"iterator": "cpp",
"memory": "cpp",
"memory_resource": "cpp",
"numeric": "cpp",
"random": "cpp",
"string_view": "cpp",
"system_error": "cpp",
"tuple": "cpp",
"type_traits": "cpp",
"utility": "cpp",
"initializer_list": "cpp",
"iosfwd": "cpp",
"iostream": "cpp",
"istream": "cpp",
"limits": "cpp",
"new": "cpp",
"numbers": "cpp",
"ostream": "cpp",
"sstream": "cpp",
"stdexcept": "cpp",
"streambuf": "cpp",
"typeinfo": "cpp"
}
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -6,7 +6,7 @@
/* By: fgras-ca <fgras-ca@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/05/09 14:07:00 by fgras-ca #+# #+# */
/* Updated: 2024/05/09 14:33:20 by fgras-ca ### ########.fr */
/* Updated: 2024/05/10 14:10:35 by fgras-ca ### ########.fr */
/* */
/* ************************************************************************** */
@ -17,6 +17,7 @@
#include <sys/socket.h>
#include <unistd.h>
#include <cstring>
#include <iostream>
class Client {
public:
@ -25,12 +26,16 @@ public:
void sendMessage(const std::string& message);
std::string receiveMessage();
void setNickname(const std::string& newNickname); // Ajout de la méthode setNickname
void setNickname(const std::string& newNickname);
std::string getNickname() const; // Ajout de la méthode getNickname
int getSocket() const;
private:
int socket;
std::string nickname;
std::string nickname; // Assurez-vous que cette donnée membre est accessible via getNickname
std::string username;
};
#endif

View File

@ -6,7 +6,7 @@
/* By: fgras-ca <fgras-ca@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/05/09 14:01:12 by fgras-ca #+# #+# */
/* Updated: 2024/05/09 14:39:02 by fgras-ca ### ########.fr */
/* Updated: 2024/05/10 14:10:44 by fgras-ca ### ########.fr */
/* */
/* ************************************************************************** */
@ -15,8 +15,6 @@
#include <string>
#include <vector>
#include "Client.hpp"
#include "CommandHandler.hpp"
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
@ -24,7 +22,21 @@
#include <iostream>
#include <stdexcept>
#include <cerrno>
#include <pthread.h>
#include "Client.hpp" // Assurez-vous que Client est inclus avant Server
#include "CommandHandler.hpp"
class Server; // Déclaration anticipée de Server si nécessaire
// Structure pour passer des données aux threads
struct ClientContext {
Client* client;
Server* server;
CommandHandler* cmdHandler;
ClientContext(Client* c, Server* s, CommandHandler* ch) : client(c), server(s), cmdHandler(ch) {}
};
class Server {
public:
Server(int port, const std::string& password);
@ -37,9 +49,11 @@ private:
int port; // Port number to bind the server
std::string password; // Server password for client connections
bool running; // Server running status
std::vector<Client*> clients; // List of connected clients
std::vector<pthread_t> threads; // List of threads for client management
void manageClient(Client* client, CommandHandler& cmdHandler);
static void *manageClient(void *clientContext); // Static to be compatible with pthread
};
#endif // SERVER_HPP

Binary file not shown.

View File

@ -6,11 +6,13 @@
/* By: fgras-ca <fgras-ca@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/05/09 14:07:27 by fgras-ca #+# #+# */
/* Updated: 2024/05/09 14:33:11 by fgras-ca ### ########.fr */
/* Updated: 2024/05/10 13:33:20 by fgras-ca ### ########.fr */
/* */
/* ************************************************************************** */
#include "Client.hpp"
#include <cstring>
#include <sys/socket.h>
Client::Client(int socket, const std::string& nickname, const std::string& username)
: socket(socket), nickname(nickname), username(username) {}
@ -20,19 +22,38 @@ Client::~Client() {
}
void Client::sendMessage(const std::string& message) {
std::cout << "Sending message: " << message << std::endl;
send(socket, message.c_str(), message.size(), 0);
}
std::string Client::receiveMessage() {
char buffer[1024];
std::memset(buffer, 0, sizeof(buffer));
int len = recv(socket, buffer, sizeof(buffer), 0);
int len = recv(socket, buffer, sizeof(buffer) - 1, 0);
if (len > 0) {
return std::string(buffer, len);
buffer[len] = '\0'; // Ensure null termination
std::string received(buffer);
// Erase newline and carriage return characters
size_t pos;
while ((pos = received.find_first_of("\r\n")) != std::string::npos) {
received.erase(pos, 1);
}
std::cout << "Received message: [" << received << "]" << std::endl;
return received;
}
return "";
}
void Client::setNickname(const std::string& newNickname) {
nickname = newNickname;
}
std::string Client::getNickname() const {
return nickname;
}
int Client::getSocket() const {
return socket;
}

View File

@ -6,7 +6,7 @@
/* By: fgras-ca <fgras-ca@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/05/09 14:19:15 by fgras-ca #+# #+# */
/* Updated: 2024/05/09 14:33:32 by fgras-ca ### ########.fr */
/* Updated: 2024/05/10 12:33:00 by fgras-ca ### ########.fr */
/* */
/* ************************************************************************** */
@ -62,9 +62,11 @@ void CommandHandler::handleNick(const std::string& command, Client* client) {
std::vector<std::string> tokens = split(command, ' ');
if (tokens.size() > 1) {
client->setNickname(tokens[1]);
std::cout << "Nickname set to: " << tokens[1] << std::endl; // Afficher et enregistrer l'action
}
}
void CommandHandler::handlePrivmsg(const std::string& command, Client* client) {
std::vector<std::string> tokens = split(command, ' ');
if (tokens.size() > 2) {

View File

@ -6,90 +6,115 @@
/* By: fgras-ca <fgras-ca@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/05/09 14:01:34 by fgras-ca #+# #+# */
/* Updated: 2024/05/09 14:48:31 by fgras-ca ### ########.fr */
/* Updated: 2024/05/10 14:13:02 by fgras-ca ### ########.fr */
/* */
/* ************************************************************************** */
// Server.cpp
#include "Server.hpp"
Server::Server(int port, const std::string& password) : port(port), password(password), running(false) {}
Server::~Server() {
// Nettoyage des ressources si nécessaire
close(listener); // Assurez-vous de fermer le socket d'écoute
// Nettoyage des clients dynamiquement alloués, si vous ne l'avez pas déjà fait
for (std::vector<Client*>::iterator it = clients.begin(); it != clients.end(); ++it) {
delete *it;
for (size_t i = 0; i < threads.size(); ++i) {
if (threads[i]) pthread_join(threads[i], NULL);
}
close(listener);
}
bool Server::initialize() {
struct sockaddr_in server_addr;
// Création du socket
listener = socket(AF_INET, SOCK_STREAM, 0);
if (listener == -1) {
std::cerr << "Error creating socket: " << strerror(errno) << std::endl;
return false;
}
// Préparation de l'adresse du serveur
memset(&server_addr, 0, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = INADDR_ANY;
server_addr.sin_port = htons(port);
// Liaison du socket
if (bind(listener, (struct sockaddr *)&server_addr, sizeof(server_addr)) == -1) {
std::cerr << "Error binding socket: " << strerror(errno) << std::endl;
close(listener);
return false;
}
// Mise en écoute du socket
if (listen(listener, 10) == -1) { // backlog set to 10
if (listen(listener, 10) == -1) {
std::cerr << "Error listening: " << strerror(errno) << std::endl;
close(listener);
return false;
}
std::cout << "Server initialized and listening on port " << port << std::endl;
running = true;
return true;
}
void Server::run() {
running = true;
struct sockaddr_in client_addr;
socklen_t client_len = sizeof(client_addr);
CommandHandler cmdHandler;
if (!running) {
std::cerr << "Server not initialized or already running." << std::endl;
return;
}
CommandHandler cmdHandler;
while (running) {
struct sockaddr_in client_addr;
socklen_t client_len = sizeof(client_addr);
int client_sock = accept(listener, (struct sockaddr *)&client_addr, &client_len);
if (client_sock == -1) {
std::cerr << "Error accepting connection: " << strerror(errno) << std::endl;
continue;
}
std::cout << "Client connected: " << client_sock << std::endl;
try {
// Créez un nouvel objet Client avec des valeurs par défaut pour nickname et username
Client* newClient = new Client(client_sock, "DefaultNickname", "DefaultUsername");
std::string welcomeMsg = "Welcome to the IRC Server!\n";
newClient->sendMessage(welcomeMsg);
manageClient(newClient, cmdHandler);
} catch (const std::exception& e) {
std::cerr << "Exception handling client: " << e.what() << std::endl;
close(client_sock);
}
Client* newClient = new Client(client_sock, "DefaultNickname", "DefaultUsername");
ClientContext* context = new ClientContext(newClient, this, &cmdHandler);
pthread_t thread;
pthread_create(&thread, NULL, &Server::manageClient, context);
pthread_detach(thread);
threads.push_back(thread);
}
}
void Server::manageClient(Client* client, CommandHandler& cmdHandler) {
// Boucle pour recevoir les commandes du client
while (running) {
std::string command = client->receiveMessage();
if (command.empty()) break; // Client disconnected
cmdHandler.handleCommand(command, client);
void* Server::manageClient(void *clientContext) {
ClientContext* ctx = static_cast<ClientContext*>(clientContext);
Client* client = ctx->client;
Server* server = ctx->server;
client->sendMessage("Welcome to the IRC Server!\n");
client->sendMessage("Password required:\n");
std::string passwordInput = client->receiveMessage();
std::cout << "Received password: [" << passwordInput << "]" << std::endl;
if (passwordInput != server->password) {
client->sendMessage("Incorrect password.\n");
std::cout << "Password mismatch." << std::endl;
close(client->getSocket());
delete client;
delete ctx;
return NULL;
}
delete client; // Cleanup when client disconnects
client->sendMessage("Password correct.\n");
std::string command;
while ((command = client->receiveMessage()) != "") {
ctx->cmdHandler->handleCommand(command, client);
if (command == "QUIT") break;
}
close(client->getSocket());
delete client;
delete ctx;
return NULL;
}

View File

@ -317,3 +317,5 @@ Scalabilité : Pensez à la scalabilité de votre serveur avec ces nouvelles fon
Conformité aux standards : Même pour les fonctionnalités bonus, tenez-vous aux standards IRC et aux bonnes pratiques de programmation pour garantir que votre serveur peut interagir correctement avec d'autres clients et serveurs IRC.
Ces fonctionnalités bonus peuvent grandement enrichir l'expérience utilisateur sur votre serveur IRC, le rendant plus attractif et plus utile pour vos utilisateurs.
Dans le cadre de notre projet nous utiliserons hexcat comme reference de client irc.