85 lines
2.4 KiB
Python
85 lines
2.4 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
Servidor de mensajería simple (broadcast) - puerto 3333
|
|
|
|
Ejecutar en un terminal separado:
|
|
python3 servidor.py
|
|
|
|
"""
|
|
import socket
|
|
import threading
|
|
|
|
HOST = '0.0.0.0'
|
|
PORT = 3333
|
|
|
|
clients = []
|
|
clients_lock = threading.Lock()
|
|
|
|
def broadcast(message: bytes, sender: socket.socket):
|
|
with clients_lock:
|
|
for client in list(clients):
|
|
if client is sender:
|
|
continue
|
|
try:
|
|
client.sendall(message)
|
|
except Exception:
|
|
try:
|
|
client.close()
|
|
except Exception:
|
|
pass
|
|
clients.remove(client)
|
|
|
|
def handle_client(client_socket: socket.socket, client_address):
|
|
print(f"[NUEVO CLIENTE] {client_address} conectado.")
|
|
try:
|
|
while True:
|
|
data = client_socket.recv(4096)
|
|
if not data:
|
|
break
|
|
text = data.decode('utf-8', errors='replace')
|
|
print(f"[{client_address}] {text}")
|
|
# Re-enviar a los demás
|
|
broadcast(data, client_socket)
|
|
except Exception as e:
|
|
print(f"[ERROR] {client_address}:", e)
|
|
finally:
|
|
with clients_lock:
|
|
if client_socket in clients:
|
|
clients.remove(client_socket)
|
|
try:
|
|
client_socket.close()
|
|
except Exception:
|
|
pass
|
|
print(f"[DESCONECTADO] {client_address} cerrado.")
|
|
|
|
def start_server():
|
|
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
|
server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
|
|
server.bind((HOST, PORT))
|
|
server.listen(10)
|
|
print(f"[INICIO] Servidor escuchando en {HOST}:{PORT}")
|
|
|
|
try:
|
|
while True:
|
|
client_socket, client_address = server.accept()
|
|
with clients_lock:
|
|
clients.append(client_socket)
|
|
t = threading.Thread(target=handle_client, args=(client_socket, client_address), daemon=True)
|
|
t.start()
|
|
except KeyboardInterrupt:
|
|
print('\n[APAGANDO] Servidor detenido por el usuario')
|
|
finally:
|
|
with clients_lock:
|
|
for c in clients:
|
|
try:
|
|
c.close()
|
|
except Exception:
|
|
pass
|
|
try:
|
|
server.close()
|
|
except Exception:
|
|
pass
|
|
|
|
if __name__ == '__main__':
|
|
start_server()
|