Introducción a los Sockets en Programación: Teoría y Ejemplos Prácticos

Los sockets son uno de los componentes clave en la comunicación en redes, permitiendo que las aplicaciones intercambien datos a través de una red local o global. Este artículo presenta los conceptos teóricos y ejemplos de código necesarios para comenzar a trabajar con sockets, enfocados principalmente en Python.


¿Qué es un socket?

Un socket es un punto final de comunicación entre dos sistemas. Se utiliza para enviar y recibir datos a través de redes usando protocolos como TCP (Protocolo de Control de Transmisión) y UDP (Protocolo de Datagrama de Usuario).

  • TCP: Protocolo orientado a la conexión que garantiza la entrega de los datos en el orden correcto.
  • UDP: Protocolo sin conexión que no garantiza la entrega de los datos, pero es más rápido.

Elementos Básicos de un Socket

  1. Dirección IP: Identifica el dispositivo en la red.
  2. Puerto: Define un punto específico para la comunicación.
  3. Protocolo: Determina cómo se transmiten los datos (TCP o UDP).

Modelo Cliente-Servidor

El modelo cliente-servidor es la base de muchas aplicaciones de red. En este modelo:

  • El servidor escucha conexiones en un puerto específico y espera solicitudes.
  • El cliente se conecta al servidor, envía solicitudes y recibe respuestas.

Código Base para un Cliente-Servidor TCP

Servidor Básico

Este servidor escucha en un puerto y responde a los mensajes del cliente convirtiéndolos a mayúsculas:

import socket

class BasicServer:
    def __init__(self, host='127.0.0.1', port=65432):
        self.host = host
        self.port = port

    def start_server(self):
        with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
            s.bind((self.host, self.port))
            s.listen()
            print(f"Servidor escuchando en {self.host}:{self.port}")
            conn, addr = s.accept()
            with conn:
                print(f"Conexión establecida con {addr}")
                while True:
                    data = conn.recv(1024)
                    if not data:
                        break
                    response = data.decode('utf-8').upper()
                    conn.sendall(response.encode('utf-8'))

if __name__ == "__main__":
    BasicServer().start_server()

Cliente Básico

El cliente se conecta al servidor y envía un mensaje:

import socket

class BasicClient:
    def __init__(self, host='127.0.0.1', port=65432):
        self.host = host
        self.port = port

    def start_client(self, message):
        with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
            s.connect((self.host, self.port))
            s.sendall(message.encode('utf-8'))
            data = s.recv(1024)
            print(f"Respuesta del servidor: {data.decode('utf-8')}")

if __name__ == "__main__":
    BasicClient().start_client("Hola, servidor")

Servidor con Múltiples Clientes usando Hilos

Para manejar varias conexiones simultáneas:

import socket
import threading

class EchoServer:
    def __init__(self, host='127.0.0.1', port=65432):
        self.host = host
        self.port = port

    def handle_client(self, conn, addr):
        print(f"Conexión establecida con {addr}")
        with conn:
            while True:
                data = conn.recv(1024)
                if not data or data.decode('utf-8').strip().upper() == 'QUIT':
                    break
                conn.sendall(data.upper())
        print(f"Conexión cerrada con {addr}")

    def start_server(self):
        with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
            s.bind((self.host, self.port))
            s.listen()
            print(f"Servidor de eco escuchando en {self.host}:{self.port}")
            while True:
                conn, addr = s.accept()
                threading.Thread(target=self.handle_client, args=(conn, addr)).start()

if __name__ == "__main__":
    EchoServer().start_server()

Servidor y Cliente UDP con Broadcast

Servidor UDP

El servidor escucha mensajes broadcast:

import socket

class UDPServer:
    def __init__(self, port=65432):
        self.port = port

    def start_server(self):
        with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as s:
            s.bind(('', self.port))
            print(f"Servidor UDP escuchando en puerto {self.port}")
            while True:
                data, addr = s.recvfrom(1024)
                print(f"Mensaje recibido de {addr}: {data.decode('utf-8')}")
                s.sendto("Mensaje recibido".encode('utf-8'), addr)

if __name__ == "__main__":
    UDPServer().start_server()

Cliente UDP

El cliente envía mensajes broadcast:

import socket

class UDPClient:
    def __init__(self, broadcast_ip='255.255.255.255', port=65432):
        self.broadcast_ip = broadcast_ip
        self.port = port

    def start_client(self, message):
        with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as s:
            s.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
            s.sendto(message.encode('utf-8'), (self.broadcast_ip, self.port))
            s.settimeout(2.0)
            try:
                while True:
                    data, addr = s.recvfrom(1024)
                    print(f"Respuesta del servidor {addr}: {data.decode('utf-8')}")
            except socket.timeout:
                print("Tiempo de espera agotado.")

if __name__ == "__main__":
    UDPClient().start_client("Mensaje de prueba")

Prácticas Recomendadas

  1. Usa siempre bloques try/except para manejar errores.
  2. Configura direcciones IP y puertos de manera dinámica para pruebas.
  3. Documenta tu código para facilitar la comprensión.

Con esta teoría y ejemplos, estarás listo para trabajar con sockets en aplicaciones de red. La clave es practicar y experimentar con diferentes configuraciones y escenarios.

close up photo of programming of codes
Photo by luis gomes on Pexels.com

Deja un comentario

Información básica sobre protección de datos Ver más

  • Responsable: Tomas Gonzalez.
  • Finalidad:  Moderar los comentarios.
  • Legitimación:  Por consentimiento del interesado.
  • Destinatarios y encargados de tratamiento:  No se ceden o comunican datos a terceros para prestar este servicio.
  • Derechos: Acceder, rectificar y suprimir los datos.
  • Información Adicional: Puede consultar la información detallada en la Política de Privacidad.

error: Content is protected !!

Descubre más desde Tomás González: Formador y Desarrollador Web

Suscríbete ahora para seguir leyendo y obtener acceso al archivo completo.

Seguir leyendo

Este sitio web utiliza cookies, si necesitas más información puedes visitar nuestra política de privacidad    Ver
Privacidad