Servidor IRC desde cero en C++
🌐 Un proyecto de 42 que implementa un servidor IRC funcional con gestión de múltiples clientes, canales y protocolo estándar.
🔍 IRC • 🛠️ Técnicas • 📦 Instalación • ⚙️ Funcionalidades • 🏗️ Arquitectura • 👥 Autores
ft_irc propone crear un servidor IRC (Internet Relay Chat) completamente funcional, implementando el protocolo de comunicación en tiempo real que permite a los clientes autenticarse, unirse a canales, enviar mensajes privados y gestionar operaciones de canal.
El proyecto utiliza I/O no bloqueante con poll(), sockets TCP/IP, y cumple con el estándar C++98. Incluye autenticación por contraseña, gestión de canales con operadores, comandos IRC estándar (KICK, INVITE, TOPIC, MODE) y un bot integrado como bonus.
- 🔐 Autenticación por contraseña con PASS/NICK/USER
- 💬 Mensajería privada entre usuarios (PRIVMSG)
- 📢 Canales de chat con broadcast a todos los miembros
- 👮 Operadores de canal con privilegios especiales
- 🔧 Comandos de operador: KICK, INVITE, TOPIC, MODE
- 🔄 Modos de canal: invite-only (i), topic restringido (t), clave (k), operador (o), límite de usuarios (l)
- ⚡ I/O no bloqueante con
poll()para múltiples clientes simultáneos - 🌐 Comunicación TCP/IP compatible con clientes IRC estándar
- 🤖 Bot integrado con comandos interactivos (!help, !rules, !quote, !stats, !time, !ops)
- 📦 Transferencia de archivos mediante DCC
- 📋 WHOIS — Información detallada de un usuario
- 📜 LIST — Listado de canales activos
- 🔔 NOTICE — Mensajes sin respuesta automática
- 🚪 PART — Salir de un canal
Internet Relay Chat es un protocolo de comunicación basado en texto que permite mensajería en tiempo real. A diferencia de los chats modernos, IRC opera sobre una arquitectura cliente-servidor donde:
- Conexión: El cliente se conecta al servidor por TCP/IP
- Autenticación: Envía contraseña, nickname y username
- Interacción: Se une a canales, envía mensajes, ejecuta comandos
- Gestión: Los operadores administran canales y usuarios
- Socket TCP: Comunicación fiable entre cliente y servidor
- Poll: Multiplexación de I/O para múltiples clientes
- Buffer de comandos: Reconstrucción de mensajes parciales
- Protocolo IRC: Parsing y ejecución de comandos estándar
- Socket no bloqueante: Configurado con
fcntl(fd, F_SETFL, O_NONBLOCK) - Multiplexación con poll(): Un único
poll()gestiona lectura, escritura y escucha - Gestión de conexiones: Accept, recv y send sin bloqueo del servidor
- Buffer de reconstrucción: Agregación de paquetes parciales (compatible con
ncy Ctrl+D)
- Parsing de comandos: Tokenización y distribución a handlers específicos
- Prefijos IRC: Formato estándar
nick!user@hosten todos los mensajes - Códigos numéricos: Respuestas RPL y ERR según el estándar (001, 401, 461, etc.)
- Registro de cliente: Flujo PASS → NICK → USER con validación completa
- Creación dinámica: Los canales se crean al primer JOIN y se eliminan cuando quedan vacíos
- Sistema de operadores: El primer usuario en unirse recibe privilegios automáticamente
- Modos de canal: Invite-only, topic restringido, clave, límite de usuarios
- Lista de invitados: Sistema de invitaciones para canales invite-only
- Broadcast eficiente: Mensajes enviados a todos los miembros excepto al emisor
- Ownership claro: El servidor gestiona el ciclo de vida de clientes y canales
- Limpieza en desconexión: Eliminación de cliente de todos los canales, liberación de memoria y cierre de FD
- Buffer overflow protection: Límite de 8192 bytes por buffer de cliente
- Manejo de errores de envío: Detección de EPIPE/ECONNRESET para clientes desconectados
# Clonar el repositorio
git clone https://github.com/ccheerry/ft_irc.git
cd ft_irc
# Compilar el proyecto
make
# El ejecutable 'ircserv' se generará en el directorio raíz# Iniciar el servidor
./ircserv <puerto> <contraseña># Usando HexChat (cliente de referencia)
# https://hexchat.github.io/downloads.html
# Usando nc para pruebas manuales
nc -C 127.0.0.1 6667| Comando | Descripción | Ejemplo |
|---|---|---|
PASS |
Autenticación con contraseña | PASS mypassword |
NICK |
Establecer nickname | NICK alvaro |
USER |
Establecer username y realname | USER alvaro 0 * :Alvaro C. |
| Comando | Descripción | Ejemplo |
|---|---|---|
JOIN |
Unirse a un canal | JOIN #general |
PART |
Salir de un canal | PART #general :Hasta luego |
PRIVMSG |
Enviar mensaje a canal o usuario | PRIVMSG #general :Hola! |
NOTICE |
Enviar notificación | NOTICE nick :info |
LIST |
Listar canales | LIST |
| Comando | Descripción | Ejemplo |
|---|---|---|
KICK |
Expulsar usuario del canal | KICK #general nick :razón |
INVITE |
Invitar usuario a un canal | INVITE nick #general |
TOPIC |
Ver/cambiar topic del canal | TOPIC #general :Nuevo topic |
MODE |
Cambiar modos del canal | MODE #general +it |
| Modo | Descripción | Ejemplo |
|---|---|---|
i |
Canal solo por invitación | MODE #ch +i |
t |
Topic restringido a operadores | MODE #ch +t |
k |
Establecer/quitar clave | MODE #ch +k secret |
o |
Dar/quitar operador | MODE #ch +o nick |
l |
Establecer/quitar límite de usuarios | MODE #ch +l 10 |
| Comando | Descripción | Ejemplo |
|---|---|---|
WHOIS |
Info de un usuario | WHOIS nick |
PING |
Mantener conexión activa | PING :token |
QUIT |
Desconectarse del servidor | QUIT :Adiós |
| Comando | Descripción |
|---|---|
!help |
Muestra lista de comandos disponibles |
!rules |
Muestra las reglas del canal |
!about |
Información sobre el bot |
!quote |
Frase aleatoria |
!stats |
Estadísticas del canal |
!time |
Hora actual del servidor |
!ops |
Lista de operadores del canal |
ft_irc/
├── include/
│ ├── ircserv.hpp # Header principal con includes y forward declarations
│ ├── Server.hpp # Clase servidor: networking, poll, gestión de clientes
│ ├── Client.hpp # Clase cliente: datos de conexión, buffer, estado
│ ├── Channel.hpp # Clase canal: miembros, operadores, modos
│ └── Bot.hpp # Clase bot: comandos interactivos
├── src/
│ ├── main.cpp # Entry point, validación de argumentos
│ ├── Server.cpp # Setup de socket, poll loop, accept/recv/send
│ ├── Commands.cpp # Handlers de todos los comandos IRC
│ ├── Client.cpp # Gestión de estado del cliente y buffer
│ ├── Channel.cpp # Lógica de canal, broadcast, operadores
│ └── Bot.cpp # Implementación de comandos del bot
├── Makefile # Compilación
└── .gitignore
┌─────────────────────────────────────────────────────────┐
│ Server │
│ - _serverFd: socket principal │
│ - _pollFds: vector de file descriptors monitoreados │
│ - _clients: map<fd, Client*> │
│ - _channels: map<nombre, Channel*> │
│ - _bot: Bot* │
│ + start() → setup_server() │
│ + run() → poll loop principal │
│ + process_command() → distribuye a handlers │
└─────────────────────────────────────────────────────────┘
│ gestiona │ gestiona
▼ ▼
┌─────────────────┐ ┌──────────────────────┐
│ Client │ │ Channel │
│ - _fd │ │ - _name │
│ - _nickname │ │ - _clients: set │
│ - _username │ │ - _operators: set │
│ - _buffer │ │ - _inviteOnly │
│ - _registered │ │ - _topicRestricted │
│ + get_prefix() │ │ - _key, _userLimit │
└─────────────────┘ │ + broadcast() │
└──────────────────────┘
- Accept: El servidor acepta la conexión TCP y crea un
Client - PASS: El cliente envía la contraseña del servidor
- NICK: El cliente elige un nickname único
- USER: El cliente proporciona username y realname
- Registro: Si PASS es correcto y NICK/USER están completos, se envía RPL_WELCOME (001)
El servidor usa un único poll() para monitorear todos los file descriptors:
- El socket del servidor detecta nuevas conexiones (POLLIN → accept)
- Los sockets de clientes detectan datos entrantes (POLLIN → recv)
- Los datos se acumulan en el buffer del cliente hasta encontrar
\n - Los comandos completos se extraen y procesan uno a uno
El servidor maneja correctamente datos parciales:
- Cada cliente tiene un buffer persistente
- Los datos se agregan al buffer con cada
recv() - Solo se procesan líneas completas (terminadas en
\n)
Los mensajes de canal se envían directamente mediante send() a cada miembro:
- Se excluye al emisor del broadcast (excepto para JOIN, MODE, etc.)
- Se detectan clientes desconectados por errores de envío (EPIPE, ECONNRESET)
- El bot envía sus mensajes como un usuario virtual con prefijo propio
- RFC 2812 - IRC: Client Protocol
- RFC 1459 - Internet Relay Chat Protocol
- Modern IRC Client Protocol
- Commands
- Sockets TCP/IP: socket, bind, listen, accept, send, recv
- I/O Multiplexing: poll, non-blocking I/O con fcntl
- Protocolo IRC: Parsing de comandos, códigos numéricos, prefijos
- Gestión de memoria: Ownership de objetos, limpieza en desconexión
- Programación en C++98: STL containers, iteradores, sin features modernos
Desarrollado como proyecto de 42 Madrid
