Proyecto control de estado de usuarios conectados

master
DevManuel19 9 months ago
commit d87199c089

@ -0,0 +1,96 @@
SERVIDOR DE ESTADO DE CLIENTES
REQUISITOS
· Servidor multiusuario
· Controla en todo momento cuantos clientes tiene conectados (hilos)
· Un cliente cuando se conecta envía su propio nombre.
· Cada 5 minutos envía un mensaje a todos los clientes indicando el número de ordenadores que tiene conectado.
· Si un cliente se desconecta, envía un mensaje a todos avisando que se ha desconectado
------------
| SERVIDOR |
------------
-- MÉTODO INICIAR SERVIDOR
Este método se encarga de iniciar el servidor. Toma como argumentos el host (dirección IP) y el puerto en el que se escucharán las conexiones entrantes de los clientes, con ello crea un socket y lo enlaza al host y puerto especificado.
Pone el socket en modo de escucha para aceptar conexiones entrantes e inicia un bucle infinito para escuchar conexiones.
Por cada conexión entrante, crea un hilo separado para manejar al cliente.
-- MANEJAR_CLIENTES
Este metodo maneja la forma de interactuar del cliente con el servidor de forma individual, recibe como argumentos el socket del cliente y el diccionario de los clientes conectados.
Espera a recibir el nombre del cliente y luego lo agrega al diccionario.
En un bucle infinito, espera 5 segundos y luego:
Actualiza la lista de usuarios y el contador de usuarios en la interfaz gráfica del servidor.
Envía al cliente un mensaje con el número de clientes conectados.
Maneja cualquier excepción que pueda ocurrir durante la comunicación con el cliente, eliminando al cliente del diccionario y cerrando su socket.
Informa a los demás clientes sobre la desconexión del cliente actual.
ACTUALIZAR LISTA USUARIOS
Este método actualiza la lista de usuarios en la interfaz gráfica del servidor.
Este método se encarga de actualizar la lista de usuarios de la interfaz gráfica asocciada al servidor, como argumentos recibe el diccionario de clientes y obtiene los nombres.
Cada vez limia la interfaz y los agrega a la vista.
ACTUALIZAR CONTADOR USUARIOS
Este método actualiza el contador de usuarios en la interfaz gráfica del servidor, recibe como argumento el contador de usuarios.
Actualiza el texto del contador con el número de usuarios conectados.
GENERAR INTERFAZ
Este métods se encarga de generar la interfaz grafica estableciendo el diseño correspondiente,
con un contador y una lista de usuarios conectados.
Espera en bucle la interaccion de los clientes.
MAIN
Simplemente es el bloque de inicializacion de la aplicacion
------------
| CLIENTE |
------------
PRINCIPAL:
Esta funcion se encarga de generar la interfaz gráfica del cliente, utilizando Tkinter,
ademas de establecer una entrada de texto para el nombre del cliente junto con dos botones para
enviar el nombre del cliente al servidor y desconectarse del mismo.
Esta función es el punto de entrada principal para la interfaz gráfica del cliente.
Establece los eventos de clic de los botones para llamar a las funciones correspondientes enviar_nombre_callback y desconectar.
ENVIAR NOMBRE
Esta función se encarga de enviar el nombre ingresado por el usuario al servidor.
Recibe como argumentos el nombre ingresado por el usuario, el campo de entrada de nombre y el botón de enviar.
Si la conexión esta en modo activa, envia el nombre al servidor utilizando el socket del cliente.
Espera recibir la respuesta del servidor para imprimirlo por consola.
Deshabilita el campo de entrada y el botón de enviar después de enviar el nombre para evitar que el cliente haga envios repetidos.
DESCONECTAR
Esta función se encarga de desconectar al cliente del servidor.
Si la conexión está activa (true), envía al servidor un mensaje para desconectarse y cierra el socket del cliente.
Después de desconectar, cambia el estado de conectado (false).
MAIN
Simplemente es el bloque de inicializacion de la aplicacion

@ -0,0 +1,72 @@
import socket
import tkinter as tk
# CREAR SOCKET TCP/IP
socket_cliente = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
socket_cliente.connect(('localhost', 8088))
#ESTADO CONEXION
conectado = True
def principal():
# VENTANA
raiz = tk.Tk()
raiz.title("Cliente")
# LABEL INGRESAR NOMBRE
entrada_nombre = tk.Entry(raiz, font=("Arial", 14))
entrada_nombre.pack(pady=10)
# ENVIAR NOMBRE AL SERVIDOR
def enviar_nombre_callback():
nombre = entrada_nombre.get()
enviar_nombre(nombre, entrada_nombre, boton_enviar)
# Botón para enviar el nombre
boton_enviar = tk.Button(raiz, text="Enviar Nombre", command=enviar_nombre_callback)
boton_enviar.pack(pady=5)
# Botón para desconectar
boton_desconectar = tk.Button(raiz, text="Desconectar", command=desconectar)
boton_desconectar.pack(pady=5)
# Iniciar el bucle de eventos de la interfaz gráfica
raiz.mainloop()
def enviar_nombre(nombre, entrada_nombre, boton_enviar):
global conectado
try:
if conectado:
# ENVIAR NOMBRE
socket_cliente.send(nombre.encode())
#RESPUESTA SERVIDOR
respuesta = socket_cliente.recv(1024).decode()
print(respuesta)
# DESHABILITAR
entrada_nombre.config(state=tk.DISABLED)
boton_enviar.config(state=tk.DISABLED)
except Exception as e:
print("Error:", e)
conectado = False
def desconectar():
global conectado
try:
if conectado:
# NOTIFICAR AL SERVIDOR
socket_cliente.send("desconectar".encode())
# CERRAR SOCKET
socket_cliente.close()
conectado = False
except Exception as e:
print("Error al desconectar:", e)
# BLOQUE DE INICIALIZACION
if __name__ == "__main__":
principal()

@ -0,0 +1,125 @@
import socket
import threading
import time
import tkinter as tk
#LISTA USUARIOS
lista_usuarios = None
def iniciar_servidor(host, puerto):
global lista_usuarios
#SOCKET
socket_servidor = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
socket_servidor.bind((host, puerto))
#ESCUCHA
socket_servidor.listen(1)
print(f"SERVIDOR INICIADO EN LA DIRECCION {host}:{puerto}")
# DICCIONARIO
clientes = {}
# BUCLE INFINITO PARA ACCEPTAR CONEXIONES
while True:
# ACCEPTAR CONEXION
socket_cliente, direccion = socket_servidor.accept()
# CREAR UN NUEVO HILO POR CADA CLIENTE
hilo_cliente = threading.Thread(target=manejar_cliente, args=(socket_cliente, clientes))
hilo_cliente.start()
def manejar_cliente(socket_cliente, clientes):
# NOMBRE CLIENTE
nombre = socket_cliente.recv(1024).decode()
# AGREGAMOS CLIENTES AL DICCIONARIO CON UN NOMBRE
clientes[socket_cliente] = nombre
print(f"{nombre} conectado desde {socket_cliente.getpeername()}")
# Bucle infinito para manejar la interacción con el cliente
while True:
try:
# Espera 5 segundos
time.sleep(5)
# Obtiene el número de clientes conectados
clientes_conectados = len(clientes)
# Actualiza la lista de usuarios en la interfaz gráfica
actualizar_lista_usuarios(clientes)
# Actualiza el contador en la GUI del servidor
actualizar_contador_usuarios(clientes_conectados)
# Construye el mensaje con el número de clientes conectados
mensaje = f"CANTIDAD DE CLIENTES CONECTADOS: {clientes_conectados}"
# Envía el mensaje al cliente actual
socket_cliente.send(mensaje.encode())
except Exception as e:
print(e)
# Maneja cualquier excepción eliminando al cliente del diccionario y cerrando su socket
if socket_cliente in clientes:
del clientes[socket_cliente]
socket_cliente.close()
# Envía un mensaje a los clientes restantes informando que este cliente se ha desconectado
for cliente in clientes:
cliente.send(f"{nombre} DESCONECTADO".encode())
break
def actualizar_lista_usuarios(clientes):
global lista_usuarios
# Obtener los nombres de usuario de los clientes conectados
usuarios_conectados = [nombre for cliente, nombre in clientes.items()]
# Limpiar la lista de usuarios en la interfaz gráfica
lista_usuarios.delete(0, tk.END)
# Agregar los usuarios conectados a la lista de usuarios en la interfaz gráfica
for usuario in usuarios_conectados:
lista_usuarios.insert(tk.END, usuario)
def actualizar_contador_usuarios(contador):
global contador_usuarios
contador_usuarios.config(text=str(contador))
def generar_interfaz():
global lista_usuarios
global contador_usuarios
# VENTANA
ventana = tk.Tk()
ventana.title("Estado del servidor")
# CONTADOR
contador_usuarios = tk.Label(ventana, text="0", font=("Arial", 72), fg="green")
contador_usuarios.pack(pady=50)
# TITULO
titulo_nombre_clientes = tk.Label(ventana, text="NOMBRE CLIENTES CONECTADOS", font=("Arial", 18))
titulo_nombre_clientes.pack()
#LISTA USUARIOS ACTIVOS
lista_usuarios = tk.Listbox(ventana)
lista_usuarios.pack()
#ESPERAR EVENTOS
ventana.mainloop()
# Bloque principal
if __name__ == "__main__":
# Definición del host y puerto del servidor
HOST = 'localhost'
PUERTO = 8088
# Inicia el servidor en un hilo de ejecución separado
threading.Thread(target=iniciar_servidor, args=(HOST, PUERTO)).start()
# Crea la interfaz gráfica en un hilo de ejecución separado
threading.Thread(target=generar_interfaz).start()
Loading…
Cancel
Save

Powered by INFORMATICA.FP.EDU.ES.