Ejemplo de uso básico de sockets para envío de texto desde un equipo servidor a un cliente y viceversa, usando Python y la librería socket. Explicamos cómo enviar un texto desde un servidor a un cliente, tanto por la red LAN como desde Internet.

Aplicación Python servidor de socket que realizará la escucha por un puerto

El código fuente en Python de la aplicación servidor será:

import socket
import sys

# Crear socket
socketAbierto = socket.socket()

# Nombre del equipo (o IP), en blanco para localhost
# para recibir conexiones externas
equipo = input("Introduzca la dirección IP o nombre del equipo (en blanco para localhost): ")
# Puerto de escucha del servidor
puerto = int(input("Introduzca el puerto de escucha: "))

try:
    """
    El método bind conecta el socket en una tupla que especifica
    una dirección y un puerto
    """
    socketAbierto.bind((equipo, puerto))
except socket.error as message:
    print("Falló la escucha por el puerto ", puerto)
    print(message)
    sys.exit()
# Iniciamos la escucha
socketAbierto.listen()
print("Escuchando en el puerto: ", puerto)
while True:
    # A la espera de una conexión de un cliente
    connection,address = socketAbierto.accept()
    print("Cliente ", address[0],address[1], " conectado")
    # Enviar un mensaje al cliente conectado
    mensaje = "Mensaje enviado al cliente desde el servidor"
    connection.send(mensaje.encode())
    # Cerrar el socket
    connection.close()

En este caso, pediremos el puerto a usar al usuario, debe ser un puerto que no esté en uso por otra aplicación. Como servidor, dejando en blanco, usará «localhost», que es lo habitual, el servidor suele ser el que ejecute el script «servidor.py».

Aplicación Python cliente que conectará con un servidor por socket

Para los clientes socket, usaremos el siguiente código Python:

import socket
import sys

# Crear socket
socketConexion = socket.socket()

# Servidor de conexión
servidor = input("Introduzca la dirección IP o nombre del servidor: ")
# El puerto a utilizar (el servidor debe estar escuchando en este puerto)
puerto = int(input("Introduzca el puerto de conexión: "))

try:
    # Conectar el socket del cliente con el servidor en el puerto indicado
    socketConexion.connect((servidor, puerto))
except socket.error as message:
    print("Falló la conexión con el servidor {} por el puerto {}".format(servidor, puerto))
    print(message)
    sys.exit()  

# Recibir y mostrar el mensaje del servidor
mensajeServidor = socketConexion.recv(1024)
print(mensajeServidor.decode())
# Cerrar el socket
socketConexion.close()

Para el cliente, al ejecutar el programa, solicitará dirección IP o nombre DNS del servidor y el puerto de conexión. Si todo es correcto conectará con el servidor por socket y recibirá un mensaje de texto, enviado desde el servidor, para verificar que la conexión funciona correctamente.

Ejecutar servidor y mantener a la espera de conexión de clientes por sockets con Python

Para ejecutar el script de servidor, guardaremos el código fuente Python del servidor en un fichero, por ejemplo con el nombre socket_servidor.py.

Para ejecutar la aplicación será suficiente con abrir una ventana de línea de comandos, para Windows desde MS-DOS, e introduciremos el comando:

«C:/Program Files/python.exe» d:/ProyectoA_Python/Socket/socket_servidor.py

En nuestro caso suponemos que el ejecutable de Python python.exe está en C:/Program Files/ y el script socket_servidor.py está en d:/ProyectoA_Python/Socket.

En la primera ejecución puede que nos solicite confirmación el firewall de Windows para el acceso por el puerto establecido:

Ejecutar servidor y mantener a la espera de conexión de clientes por sockets con Python

Introduciremos el nombre del servidor (INTRO para dejar por defecto localhost), e introduciremos el puerto de escucha, que no debe estar en uso por ningún otro programa, por ejemplo: 2323. Si todo es correcto, el servidor mostrará el mensaje:

Escuchando en el puerto: 2323.

Quedando a la escucha, a la espera de recibir la conexión de los clientes:

Ejecutar servidor y mantener a la espera de conexión de clientes por sockets con Python

Ejecutar cliente y conectar con servidor por socket para recibir mensaje de texto con Python

Para el caso del equipo cliente, podrá ejecutarse desde el propio servidor (localhost), o bien desde cualquier otro equipo de la red. El servidor debe tener el puerto que se use abierto en el cortafuegos.

Guardaremos el script del cliente Python en un fichero con el nombre socket_cliente.py. Para ejecutarlo procederemos igual que para el servidor, desde cualquier equipo, necesitará tener instalado Python:

«C:/Program Files/python.exe» d:/ProyectoA_Python/Socket/socket_cliente.py

En el comando anterior suponemos que Python está en: C:/Program Files/ y el script socket_cliente.py está en: d:/ProyectoA_Python/Socket/.

Al ejecutarlo, nos solicitará una dirección IP o nombre DNS del servidor al que nos conectaremos y un puerto:

Si todo es correcto, mostrará el mensaje recibido del servidor:

Mensaje enviado al cliente desde el servidor

Ejecutar cliente y conectar con servidor por socket para recibir mensaje de texto con Python

En la ventana del servidor, podremos comprobar que muestra la conexión del cliente y la IP desde la que se conecta:

Ejecutar cliente y conectar con servidor por socket para recibir mensaje de texto con Python

Conexión externa por socket con Python desde Internet

Si queremos realizar la conexión desde fuera de la red LAN, desde un equipo de Internet, el código fuente Python, tanto para el cliente como para el servidor, será el mismo, no variará. Lo que sí que habrá que agregar es una regla NAT al router, para que el tráfico que venga de internet por el puerto indicado (en nuestro caso el 2323) lo redirija a la IP del equipo donde tengamos el servidor socket escuchando (en nuestro caso el equipo con IP 192.168.1.2):

Conexión externa por socket con Python desde Internet

De esta forma, y con las reglas oportunas en el firewall del equipo que permita el tráfico por el puerto 2323, de entrada:

Conexión externa por socket con Python desde Internet

Y de salida:

Conexión externa por socket con Python desde Internet

También deberemos conocer la IP pública de la conexión a Internet donde se encuentra el servidor, podremos obtenerla desde la web, que abriremos en el equipo servidor socket:

https://proyectoa.com/ip.php

Que nos devolverá:

Conexión externa por socket con Python desde Internet

Con el NAT en el router, el puerto abierto en el cortafuegos y la IP pública, podremos realizar una conexión desde un equipo de fuera de nuestra red. Será suficiente con copiar el texto del script del cliente Python, tener Python instalado, y ejecutar el comando igual que hemos hecho anteriormente, cambiando «localhost» por la IP obtenida anteriormente:

«C:\Program Files (x86)\Microsoft Visual Studio\Shared\Python37_64\python.exe» f:/cliente.py

En este caso vemos que el ejecutable de Python python.exe se encuentra en la carpeta «C:\Program Files (x86)\Microsoft Visual Studio\Shared\Python37_64\» y el script Python del cliente socket se encuentra en: f:/cliente.py.

Al ejecutar el script, como siempre, nos solicitará la IP o nombre del servidor, introduciremos la IP pública obtenida anteriormente donde se encuentra el servidor. Y nos solicitará también el puerto de conexión, introduciremos el puerto en el que esté escuchando el servidor.

Si todo es correcto, nos mostrará el mensaje recibido del servidor a través de socket por Internet:

Mensaje enviado al cliente desde el servidor

Conexión externa por socket con Python desde Internet

Y en la ventana del servidor, podremos ver que se ha establecido la conexión, e incluso la IP pública desde la que se ha conectado el cliente:

Conexión externa por socket con Python desde Internet