From 9cd3eb56a7ab36f4e2084d2aae8442a5e41606a3 Mon Sep 17 00:00:00 2001 From: Kevin William Olarte Braun Date: Wed, 19 Feb 2025 03:17:40 +0000 Subject: [PATCH] Subir archivos a "/" --- Controlador.py | 33 +++++++++++++++++++++++++++++++ Modelo.py | 53 ++++++++++++++++++++++++++++++++++++++++++++++++++ Vista.py | 43 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 129 insertions(+) create mode 100644 Controlador.py create mode 100644 Modelo.py create mode 100644 Vista.py diff --git a/Controlador.py b/Controlador.py new file mode 100644 index 0000000..811bc95 --- /dev/null +++ b/Controlador.py @@ -0,0 +1,33 @@ +import threading +from Modelo import ModeloCliente +from server import start_server + +class ControladorChat: + def __init__(self, vista): + self.vista = vista + self.modelo = ModeloCliente() + + def iniciar_servidor(self): + """Inicia el servidor en un hilo separado.""" + threading.Thread(target=start_server, daemon=True).start() + self.vista.mostrar_mensaje("[SERVIDOR] Servidor iniciado en segundo plano...\n") + + def conectar_cliente(self): + """Intenta conectar el cliente al servidor.""" + mensaje = self.modelo.conectar( + on_message_received=self.vista.mostrar_mensaje, + on_error=self.vista.mostrar_mensaje + ) + self.vista.mostrar_mensaje(mensaje) + if self.modelo.connected: + self.vista.habilitar_envio() + + def enviar_mensaje(self): + """Obtiene el mensaje de la vista y lo envía al servidor, además lo imprime en la interfaz.""" + mensaje = self.vista.message_entry.get() + if mensaje: + self.vista.mostrar_mensaje(f"[TÚ] {mensaje}") # Agregar el mensaje a la vista + error = self.modelo.enviar_mensaje(mensaje) + if error: + self.vista.mostrar_mensaje(error) + self.vista.message_entry.delete(0, 'end') # Limpiar el campo de entrada diff --git a/Modelo.py b/Modelo.py new file mode 100644 index 0000000..1b4f496 --- /dev/null +++ b/Modelo.py @@ -0,0 +1,53 @@ +import socket +import threading + +SERVER_HOST = '127.0.0.1' +SERVER_PORT = 3333 + +class ModeloCliente: + def __init__(self): + self.client_socket = None + self.connected = False + + def conectar(self, on_message_received, on_error): + """Conecta el cliente al servidor.""" + if self.connected: + on_error("[CLIENTE] Ya estás conectado al servidor.\n") + return + + self.client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + try: + self.client_socket.connect((SERVER_HOST, SERVER_PORT)) + self.connected = True + threading.Thread(target=self.recibir_mensajes, args=(on_message_received, on_error), daemon=True).start() + return f"[CONECTADO] Conectado al servidor {SERVER_HOST}:{SERVER_PORT}\n" + except ConnectionRefusedError: + self.client_socket = None + return "[ERROR] El servidor no está disponible. Inícialo primero.\n" + except Exception as e: + self.client_socket = None + return f"[ERROR] No se pudo conectar al servidor: {e}\n" + + def recibir_mensajes(self, on_message_received, on_error): + """Recibe mensajes del servidor y los muestra en la vista.""" + while True: + try: + mensaje = self.client_socket.recv(1024) + if not mensaje: + break + on_message_received(mensaje.decode('utf-8')) + except: + on_error("[ERROR] Conexión perdida con el servidor.\n") + self.client_socket.close() + self.client_socket = None + self.connected = False + break + + def enviar_mensaje(self, mensaje): + """Envía un mensaje al servidor.""" + if mensaje and self.client_socket: + try: + self.client_socket.send(mensaje.encode('utf-8')) + except: + return "[ERROR] No se pudo enviar el mensaje.\n" + return None diff --git a/Vista.py b/Vista.py new file mode 100644 index 0000000..925dcff --- /dev/null +++ b/Vista.py @@ -0,0 +1,43 @@ +import tkinter as tk +from tkinter import scrolledtext + +class VistaChat: + def __init__(self, root, controlador): + self.root = root + self.root.title("Chat Cliente-Servidor") + self.controlador = controlador + + # Botón para iniciar el servidor + self.server_button = tk.Button(root, text="Iniciar Servidor", command=self.controlador.iniciar_servidor) + self.server_button.grid(row=0, column=0, padx=10, pady=10) + + # Botón para conectar el cliente + self.connect_button = tk.Button(root, text="Conectar Cliente", command=self.controlador.conectar_cliente) + self.connect_button.grid(row=0, column=1, padx=10, pady=10) + + # Área de chat + self.chat_display = scrolledtext.ScrolledText(root, wrap=tk.WORD, state='disabled', width=50, height=20) + self.chat_display.grid(row=1, column=0, padx=10, pady=10, columnspan=2) + + # Campo de entrada de mensajes + self.message_entry = tk.Entry(root, width=40) + self.message_entry.grid(row=2, column=0, padx=10, pady=10) + + # Botón para enviar mensajes + self.send_button = tk.Button(root, text="Enviar", command=self.controlador.enviar_mensaje, state='disabled') + self.send_button.grid(row=2, column=1, padx=10, pady=10) + + def mostrar_mensaje(self, mensaje): + """Muestra un mensaje en el chat.""" + self.chat_display.config(state='normal') + self.chat_display.insert(tk.END, mensaje + '\n') + self.chat_display.config(state='disabled') + self.chat_display.yview(tk.END) + + def habilitar_envio(self): + """Habilita el botón de enviar mensajes.""" + self.send_button.config(state='normal') + + def deshabilitar_envio(self): + """Deshabilita el botón de enviar mensajes.""" + self.send_button.config(state='disabled')