Un servidor TCP es una base clásica de “Sistemas”: comunicación punto a punto, control del flujo y un protocolo propio. Aquí montamos un servidor que entiende dos comandos:
- GET nombre.txt: envía el contenido del archivo.
- END: cierra la conexión.
1) Estructura mínima de servidor
import socket
HOST = "127.0.0.1"
PORT = 5000
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind((HOST, PORT))
s.listen(1)
print(f"Servidor escuchando en {HOST}:{PORT}")
conn, addr = s.accept()
with conn:
print("Conectado:", addr)
while True:
data = conn.recv(1024)
if not data:
break
cmd = data.decode("utf-8", errors="ignore").strip()
# ... procesar comando ...
2) Protocolo: GET / END
Cuando recibimos GET archivo, leemos el fichero y lo enviamos. Para simplificar, enviamos primero una cabecera con el tamaño en bytes y luego el contenido.
from pathlib import Path
def send_file(conn, name):
p = Path(name)
if not p.exists() or not p.is_file():
conn.sendall(b"ERR Archivo no encontrado\n")
return
content = p.read_bytes()
conn.sendall(f"OK {len(content)}\n".encode("utf-8"))
conn.sendall(content)
# dentro del bucle:
if cmd.upper() == "END":
conn.sendall(b"BYE\n")
break
elif cmd.upper().startswith("GET "):
_, name = cmd.split(" ", 1)
send_file(conn, name.strip())
else:
conn.sendall(b"ERR Comando desconocido\n")
3) Detalles importantes
- TCP es un stream: lo normal es definir delimitadores (como
\n) o tamaños para separar mensajes. - Codificación: usa
utf-8para comandos; para binarios, trabaja conbytes. - Rutas: en proyectos reales, restringe a un directorio seguro para evitar path traversal.
