Fase 3: Implementación del Cliente CLI
Objetivo
Crear la lógica básica del cliente para conectarse al servidor de chat, enviar mensajes y recibir transmisiones, inicialmente usando la línea de comandos (CLI).
Conceptos Clave
Sockets TCP Cliente: Uso de sockets para conectar con el servidor. Hilos en el Cliente: Permitir el envío y recepción simultánea de mensajes. Comunicación entre Cliente y Servidor: Manejo de datos y estructuras de mensajes.
Instrucciones
1. Crear la estructura inicial del cliente
Edita src/client.py y completa la clase con las funciones esenciales:
"""
Módulo: client.py
Descripción: Define el cliente del sistema de chat local.
"""
import socket
import threading
class ChatClient:
def __init__(self, host, port):
"""
Inicializa el cliente con la dirección y puerto del servidor.
:param host: Dirección IP del servidor.
:param port: Puerto del servidor.
"""
self.host = host
self.port = port
self.client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.running = True
def connect_to_server(self):
"""
Conecta el cliente al servidor especificado.
"""
try:
self.client_socket.connect((self.host, self.port))
print("Conectado al servidor")
= input("Ingresa tu nickname: ")
nickname self.client_socket.sendall(nickname.encode("utf-8"))
except Exception as e:
print(f"No se pudo conectar al servidor: {e}")
self.running = False
def send_message(self):
"""
Envía mensajes al servidor de manera continua.
"""
while self.running:
try:
= input()
message self.client_socket.sendall(message.encode("utf-8"))
except Exception as e:
print(f"Error al enviar mensaje: {e}")
self.running = False
break
def receive_messages(self):
"""
Recibe mensajes del servidor de manera continua.
"""
while self.running:
try:
= self.client_socket.recv(1024).decode("utf-8")
message if message:
print(message)
else:
break
except Exception as e:
print(f"Error al recibir mensaje: {e}")
self.running = False
break
def start_client(self):
"""
Inicia el cliente, manejando la conexión y las operaciones.
"""
self.connect_to_server()
if self.running:
=self.receive_messages, daemon=True).start()
threading.Thread(targetself.send_message()
if __name__ == "__main__":
= "127.0.0.1"
SERVER_HOST = 12345
SERVER_PORT = ChatClient(SERVER_HOST, SERVER_PORT)
client client.start_client()
2. Probar el cliente
Asegúrate de que el servidor está corriendo:
python src/server.py
En una nueva terminal, ejecuta el cliente:
python src/client.py
Ingresa un nickname y verifica que el cliente se conecte al servidor.
Abre múltiples terminales y ejecuta el cliente en cada una para probar el sistema.
Envía mensajes entre clientes y confirma que el servidor los retransmite correctamente.
3. Agregar pruebas unitarias para el cliente
Edita tests/test_client.py para verificar casos básicos:
import unittest
from src.client import ChatClient
class TestChatClient(unittest.TestCase):
def setUp(self):
self.client = ChatClient("127.0.0.1", 12345)
def test_client_initialization(self):
self.assertEqual(self.client.host, "127.0.0.1")
self.assertEqual(self.client.port, 12345)
def test_client_socket_creation(self):
self.assertIsNotNone(self.client.client_socket)
if __name__ == "__main__":
unittest.main()
Ejecuta las pruebas:
python -m unittest discover -s tests
4. Versionar los cambios
Agrega y confirma los archivos modificados:
git add .
git commit -m "Fase 3: Implementación del cliente CLI"
Sube los cambios al repositorio remoto:
git push origin main
Pruebas
- Conecta múltiples clientes al servidor y verifica que los mensajes se retransmitan correctamente.
- Realiza pruebas unitarias para garantizar la creación adecuada del cliente.
Conclusiones
En esta fase, se desarrolló un cliente funcional basado en CLI que puede conectarse al servidor y participar en un chat en tiempo real. Los estudiantes pudieron observar cómo manejar la comunicación bidireccional utilizando sockets y threading.