📧 Comunicación entre procesos: Cliente y Servidor
🎯 Objetivo de aprendizaje
- Comprender los mecanismos de comunicación entre procesos (IPC) utilizando sockets.
- Crear un servidor y un cliente en Python.
- Identificar el rol del sistema operativo en la gestión de las conexiones de red.
📜 Enunciado
En este ejercicio, usted va a crear una aplicación simple de comunicación entre un cliente y un servidor utilizando sockets en Python.
🔧 Paso 1 – Crear un servidor simple
Un servidor:
- Abre una "puerta" (llamada puerto) en su computadora.
- Espera a que un cliente se conecte.
- Recibe los mensajes del cliente.
Código del servidor
Cree un archivo llamado serveur.py y copie el siguiente código:
import socket
# Crée un socket TCP
serveur = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# L'adresse IP et le port à utiliser
hote = 'localhost'
port = 12345
# Lier le socket à l'adresse
serveur.bind((hote, port))
# Écoute jusqu'à 1 connexion
serveur.listen(1)
print("[Serveur] En attente de connexion...")
# Accepter la connexion
connexion, adresse = serveur.accept()
print(f"[Serveur] Connexion de {adresse}")
# Réception des messages
while True:
message = connexion.recv(1024).decode()
if message.lower() == "exit":
print("[Serveur] Fin de la communication.")
break
print(f"[Client] {message}")
# Fermer les connexions
connexion.close()
serveur.close()
Prueba
Este programa no hace nada hasta que un cliente se conecta. Inicie el servidor con el comando:
python serveur.py
y conéctese con su navegador web yendo a http://localhost:12345.
Puede detener el servidor presionando Ctrl+C en la terminal.
💬 Paso 2 – Crear un cliente
Un cliente:
- Se conecta a un servidor (aquí mediante
localhosty el puerto). - Envía los mensajes que usted escribe en la consola.
2.1 Código del cliente
Cree un archivo client.py:
import socket
# Crée un socket TCP
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# Se connecter au serveur
client.connect(('localhost', 12345))
print("[Client] Connecté au serveur. Tapez vos messages :")
# Lire et envoyer les messages
while True:
message = input(">>> ")
client.sendall(message.encode())
if message.lower() == "exit":
break
# Fermer la connexion
client.close()
2.2 Prueba
- En una terminal: ejecute
python serveur.py - En otra terminal: ejecute
python client.py - Intercambie algunos mensajes.
- Escriba
exitpara detener.
🔁 Paso 3 – Comunicación en ambos sentidos
Actualmente, solo el cliente habla y el servidor escucha. Ahora vamos a permitir que el servidor responda.
3.1 Usar threading para escuchar y escribir al mismo tiempo
Cree un archivo llamado serveur2.py y copie el siguiente código:
import socket
import threading
def recevoir(connexion):
while True:
try:
message = connexion.recv(1024).decode()
if not message or message.lower() == "exit":
print("[Client] a quitté la conversation.")
print("[Serveur >>>] ", end="", flush=True)
break
print(f"[Client] {message}")
print("[Serveur >>>] ", end="", flush=True)
except: # noqa: E722
break
def envoyer(connexion):
while True:
try:
message = input("[Serveur >>>] ")
connexion.sendall(message.encode())
if message.lower() == "exit":
break
except: # noqa: E722
break
# Création du serveur
serveur = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
serveur.bind(('localhost', 12345))
serveur.listen(1)
print("[Serveur] En attente de connexion...")
connexion, adresse = serveur.accept()
print(f"[Serveur] Connecté à {adresse}")
# Démarrage des threads
thread1 = threading.Thread(target=recevoir, args=(connexion,))
thread2 = threading.Thread(target=envoyer, args=(connexion,))
thread1.start()
thread2.start()
thread1.join()
thread2.join()
connexion.close()
serveur.close()
Cree un archivo llamado client2.py y copie el siguiente código:
import socket
import threading
def recevoir(sock):
while True:
message = sock.recv(1024).decode()
if message.lower() == "exit":
print("[Serveur] a quitté la conversation.")
print("[Client >>>] ", end="", flush=True)
break
print(f"[Serveur] {message}")
print("[Client >>>] ", end="", flush=True)
def envoyer(sock):
while True:
message = input("[Client >>>] ")
sock.sendall(message.encode())
if message.lower() == "exit":
break
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect(('localhost', 12345))
print("[Client] Connecté au serveur.")
# Démarrage des threads
thread1 = threading.Thread(target=recevoir, args=(client,))
thread2 = threading.Thread(target=envoyer, args=(client,))
thread1.start()
thread2.start()
thread1.join()
thread2.join()
client.close()
✅ Resultado esperado
- Ejecute
serveur2.pyen una terminal. - Ejecute
client2.pyen otra. - Intente intercambiar mensajes en ambos sentidos.
- Cierre correctamente con
exit.

📝 Paso 4 – El sistema operativo
El sistema operativo juega un papel crucial en la gestión de las conexiones de red. Administra los recursos, los puertos y asegura que los datos se envíen y reciban correctamente. Lo mismo ocurre con los threads, que permiten ejecutar varias tareas en paralelo, como escuchar y enviar mensajes al mismo tiempo.
Responda a las siguientes preguntas:
- En el código del servidor y del cliente, ¿en qué momento está implicado el sistema operativo?
- ¿Los threads son gestionados por el sistema operativo (OS thread) o por Python (application thread)?
- ¿Por qué es importante cerrar las conexiones correctamente?
- ¿Qué sucede si intenta iniciar el servidor varias veces en el mismo puerto sin cerrarlo?
- ¿Qué sucede si intenta iniciar el cliente antes que el servidor?