Este es un servidor que utiliza sockets por medio de una conexion TCP para simular un chat similar a los clientes IRC como weechat.
Permite enviar mensajes globales o privados por medio de /msg <user> <msg>. El servidor utiliza hilos con threading para manejar a cada cliente con un diccionario y un lock para manejar la lista de usuarios conectados.
El servidor se crea utilizando socket:
socket.socket(socket.AF_INET, socket.SOCK_STREAM)Donde:
AF_INETindica el uso de direcciones IPv4SOCK_STREAMindica el uso del protocolo TCP
Las abreviaciones son heredadas de C
Para permitir que múltiples clientes se conecten simultáneamente cada que se conecta uno nuevo se delega a un hilo nuevo:
thread = threading.Thread(target=handle_client, args=(conn, addr))
thread.start()Dado que múltiples hilos pueden acceder al diccionario de clientes al mismo tiempo, existe el riesgo de race conditions:
- un hilo podría estar enviando mensajes
- mientras otro elimina un usuario desconectado
# ejemplo
with clients_lock:
clients[username] = connEl sistema permite el uso de comandos como /users y /msg:
/msg <user> <msg>
El servidor procesa este comando y envía el mensaje únicamente al destinatario.
/users
Cuando un usuario se conecta:
- el cliente envía un mensaje de login
- el servidor registra el nombre
- se añade al diccionario de clientes
- se notifica a los demás usuarios
Ejemplo de mensaje del sistema:
<user> joined the chat
Cuando el usuario se desconecta:
- se elimina del diccionario
- se envía una notificación al chat
<user> left the chat
El servidor utiliza bloques try/except para manejar errores como:
- desconexión inesperada de clientes
- errores de red
- mensajes mal formateados
Esto evita que el servidor se detenga si un cliente falla.
El modelo utilizado es un hilo por cliente, debido a que es una implementación sencilla y para la magnitud del proyecto es mas que suficiente. Para mejorar el sistema se podrian usar eventos.