Curso: Telemática
PROGRAMANDO SOCKETS EN PYTHON
Competencia: Al final el estudiante tendrá la capacidad de programar un socket que
permita tener interacción con clientes, basándose en la arquitectura cliente servidor;
bien sea, TCP o UDP de acuerdo a la necesidad que tenga que resolver.
Resultado de aprendizaje: Modela e implementa servicios orientados a la conexión y no
orientados a la conexión mediante Socket, basados en la arquitectura cliente servidor.
FUNDAMENTOS TEÓRICOS
Un socket es muy parecido a un archivo, excepto que un solo socket proporciona una
conexión bidireccional entre dos programas. Puede leer y escribir en el mismo socket.
Si escribe algo en un socket, se envía a la aplicación en el otro extremo del socket. Si
lee desde el socket, se le dan los datos que la otra aplicación ha enviado. Pero si intenta
leer un socket cuando el programa en el otro extremo del socket no ha enviado ningún
dato, simplemente se sienta y espera. Si los programas en ambos extremos del socket
esperan algunos datos sin enviar nada, esperarán mucho tiempo; por tanto, es
requerido por los programas que se comunican a través de Internet, tener algún tipo de
protocolo.
Es importante recordar que un protocolo es un conjunto de reglas precisas que
determinan quién debe ir primero, qué deben hacer y luego, cuáles son las respuestas
a ese mensaje, quién envía a continuación y así, sucesivamente. En cierto sentido, las
dos aplicaciones en cada extremo se sincronizan. En las figuras 1 y 2 se puede
apreciar cómo se generan los procesos de comunicación entre un cliente y un servidor.
Curso: Telemática
Figura 1. Comunicación de procesos por sockets mediante el protocolo TCP
Socket S S Socket
o o
Connection Internet Port Nro Connection
c Port Nro c
Send k k Send
e e
Receive t t Receive
Program Client Program Server
Figura 2. Comunicación de procesos por sockets
Sockets en Python
Python proporciona dos niveles de acceso a los servicios de red. En un nivel bajo, se
puede acceder al soporte básico socket en el sistema operativo subyacente, lo que le
permite implementar clientes y servidores para ambos protocolos, orientados a
conexión y sin conexión. Python también tiene bibliotecas que proporcionan acceso de
nivel superior a los protocolos de nivel de aplicación específicos, tales como FTP y
HTTP.
Curso: Telemática
Vocabulario de socket
Término Descripción
Dominio La familia de protocolos que se utiliza como mecanismo
de transporte. Estos valores son constantes tales como
AF_INET, PF_INET, PF_UNIX y PF_X25.
Escribe El tipo de comunicaciones entre los dos puntos finales,
normalmente SOCK_STREAM para protocolos
orientados a la conexión y SOCK_DGRAM para
protocolos sin conexión.
Protocolo Típicamente cero, esto puede ser utilizado para identificar
una variante de un protocolo dentro de un dominio y el
tipo.
Nombre de host El identificador de una interfaz de red:
Una cadena, que puede ser un nombre de host, una
dirección decimal con puntos o una dirección IPv6.
Una cadena " ", que especifica una dirección
INADDR_BROADCAST.
Una cadena de longitud cero, que especifica
INADDR_ANY.
Un entero, interpretado como una dirección binaria en
orden de bytes.
Puerto Cada servidor escucha los clientes a través de puertos.
Un puerto puede ser un número, una cadena que
contiene un número de puerto o el nombre de un
servicio.
Curso: Telemática
El módulo Socket
Para crear un socket, se debe utilizar la función [Link] () que tiene la sintaxis
general:
s = [Link] (socket_family, socket_type, protocol=0)
Esta es la descripción de los parámetros:
socket_family: Puede ser AF_UNIX o AF_INET, como se explicó anteriormente.
socket_type: Puede ser SOCK_STREAM o SOCK_DGRAM.
protocolo: Por defecto en 0.
Posteriormente, puede utilizar las funciones necesarias para crear su cliente o
programa servidor.
A continuación, se presenta la lista de funciones necesarias.
Métodos Socket Server
Procedimiento Descripción
[Link] () Este método vincula un nombre y número de puerto al socket.
[Link] () Este método permite escuchar conexiones TCP.
[Link] () Este método permite pasivamente aceptar conexión de cliente
TCP.
Curso: Telemática
Métodos Socket Cliente
Procedimiento Descripción
[Link] () Este método inicia activamente conexión de servidor TCP.
Métodos generales de Socket
Procedimiento Descripción
[Link] () Este método recibe el mensaje TCP.
[Link] () Este método transmite el mensaje TCP.
[Link] () Este método recibe el mensaje UDP.
[Link] () Este método transmite el mensaje UDP.
[Link] () Este método cierra el socket.
[Link] () Devuelve el nombre de host.
Curso: Telemática
IMPLEMENTACIÓN DE SOCKET EN PYTHON
Requisitos: Instale en su computador la última versión Python disponible, accediendo al
enlace: [Link]
A continuación, se implementarán dos servicios de la capa de transporte utilizando
Sockets en Python para UDP.
SERVIDOR UDP
from socket import *
serverPort = 12000
serverSocket=socket(AF_INET,SOCK_DGRAM)
[Link](("",serverPort))
print ("El servidor está listo para recibir peticiones")
while 1:
message, clientAddres=[Link](2048)
print ("mensaje recibido: "+[Link]())
modifiedMessage=([Link]().upper())
print ("mensaje modificado: "+modifiedMessage)
[Link]([Link](), clientAddres)
print("Se envió mensaje modificado al cliente")
Una vez digitado el código anterior ejecute este comando, si está en Windows ejecute
el comando cmd para que se abra una terminal y ejecute la siguiente línea de
comando:
python Server_UDP.py
Observe el resultado de la ejecución en la figura 3.
Curso: Telemática
Figura 3. Línea de comando para ejecutar el servidor UDP
A continuación, digite el código para el cliente UDP.
CLIENTE UDP
import socket #Librerias para utilizar Sockets
#Nombre del servidor
serverName = "localhost"
# ServerPort corresponde al puerto por donde escucha el servidor
serverPort = 12000
#Se instancia un cliente socket de tipo UDP
client_socket = [Link](socket.AF_INET, socket.SOCK_DGRAM)
#Extrae del teclado una palabra escrita por el cliente
message = input("Introduzca una palabra: ")
#Se envia por el cliente socket el texto cargado a la variable message y se
decodifica en formato uft-8
client_socket.sendto([Link]("utf-8"),(serverName, serverPort))
#La variable modifiedMessage extrae del cliente socket el mensaje
modifiedMessage, serverAddress = client_socket.recvfrom(2048)
#El mensaje es mostrado por pantalla
print (modifiedMessage)
#Se cierra la conexión al socket
client_socket.close()
Curso: Telemática
De igual forma que hizo con el servidor, en la línea de comando ejecute la siguiente línea
de instrucción:
python Client_UDP.py
Siga las instrucciones de la aplicación y observe el resultado en la figura 4.
Figura 4. Línea de comando para ejecutar el cliente UDP
Observe en la figura 5, cómo la consola del servidor muestra las peticiones que llegan
de los clientes.
Figura 5. Línea de comando del servidor recibiendo respuesta de los clientes.
Curso: Telemática
ANÁLISIS DE TRÁFICO CON WIRESHARK PARA UDP
Instale Wireshark accediendo al siguiente enlace:
[Link]
Antes de ejecutar tanto al cliente como al servidor, debe iniciar Wireshark, para ello
ejecute el Sniffer, vaya al menú Capture -> Option y seleccione la interfaz de Wireless
(Wi-Fi) cómo se aprecia en la figura 6.
Figura 6. Analizador de tráfico Wireshark
Posteriormente en la caja de texto de filtros escriba UDP, como se aprecia en la figura
7.
Curso: Telemática
Figura 7. Selección para el filtro UDP
Luego, haga clic en la lista de panel de paquetes y seleccione Ethernet, como se
aprecia en la figura 8. De esta forma podrá saber la Mac origen y la Mac destino del
tráfico UDP.
Figura 8. Lista de paquetes Ethernet
En la misma lista del panel de paquetes haga clic en Internet Protocol Version 4, como
se aprecia en la figura 9.
Curso: Telemática
Figura 9. Lista de paquetes para IP Version 4
Finalmente, para observar los puertos origen y destino del tráfico UDP del socket
implementado, nuevamente en la lista de paquetes seleccione User Datagram Protocol,
como se aprecia en la figura 10.
Figura 10. Lista de paquetes para UDP.
Curso: Telemática
SERVIDOR TCP
#Se importan todas las librerias de sockets
from socket import*
#puerto por donde escuchará el servidor
serverPort =12000
#Se instancia el servidor TCP
serverSocket = socket(AF_INET,SOCK_STREAM)
#Se define el puerto del servidor
[Link](("",serverPort))
#Servidor en modo escucha
[Link](1)
print("El servidor esta listo para recibir peticiones:")
while 1:
#Se extrae la información del puerto y la dirección ip del servidor
conSocket, addr = [Link]()
print("Recibiendo mensajes desde el cliente", addr)
#Obtiene la información extraida del cliente
msg= [Link](1024)
#Cambia el mensaje
msg_change=[Link]()
#Se le envia el mensaje al cliente
[Link](msg_change)
Una vez digitado el código anterior ejecute este comando. Si está en Windows ejecute
el comando cmd, para que se abra una terminal y ejecute la siguiente línea de
comando,como se aprecia en la figura 11.
python Server_TCP.py
Curso: Telemática
Figura 11. Línea de comando para ejecutar el servidor TCP
A continuación, digite el código para el cliente TCP
CLIENTE TCP
#Importa las librerias del sockets
from socket import*
#Se define la dirección ip a donde se va a apuntar al servidor
servername ="[Link]"
#Se define el puerto por donde escucha el servidor
serverport=12000
#Se establece la instancia del cliente sockets
clienteSocket= socket(AF_INET,SOCK_STREAM)
#Se establece la conexión con el servidor
[Link]((servername,serverport))
#Se solicita al cliente que escriba un mensaje
msg=input("Escriba una palabra")
#Se envia el mensaje al servidor con formato utf-8
Curso: Telemática
[Link]([Link]('utf-8'))
#Se obtiene mensaje cambiado por el servidor
msg_modified=[Link](1024)
#se imprime el mensaje modificado por el servidor
print("el mensaje cambiado es", msg_modified)
#Se cierra la conexión
[Link]()
Ejecute la línea de comando para cliente, como se aprecia en la figura 12.
python Client_TCP.py
Figura 12. Línea de comando para ejecutar el cliente TCP
Curso: Telemática
En la figura 13, se puede apreciar la interacción del servidor con las peticiones de los
clientes.
Figura 13. Interacción del servidor TCP con clientes TCP.
Curso: Telemática
ANÁLISIS DE TRÁFICO CON WIRESHARK PARA TCP
Observación: Siempre ejecute el Sniffer antes de ejecutar el servidor y el cliente Socket.
Filtre el tráfico TCP como se aprecia en la figura 14.
Figura 14. Filtrando tráfico TCP
A continuación, haga clic en la lista de paquetes y seleccione Ethernet, para ver la Mac
origen y Mac destino para el tráfico TCP del socket programado, como se aprecia en la
figura 15.
Curso: Telemática
Figura 15. Lista de paquetes Ethernet
A continuación, puede observar la IP origen y destino del servidor y cliente del socket
programado, tal y como se aprecia en la figura 16.
Figura 16. Lista de paquetes IP V4
Finalmente, para observar los puertos origen y destino, se hace clic en la lista de
paquetes en Transmission Control Protocol del socket programado, tal y como se aprecia
en la figura 17.
Curso: Telemática
Figura 17. Lista de paquetes TCP.
Ejercicio
A continuación, se plantea el siguiente problema.
Dado un número por consola, se le pide al servidor que determine si el número digitado
por el cliente es primo o no.
Solución:
Se modificará el Server Socket TCP y el Cliente Socket TCP, para el problema en
cuestión.
Código Server_TCP_Primos
import sys #Libreria para extraer datos del teclado
#Se importan todas las librerias de sockets
from socket import*
#puerto por donde escuchará el servidor
#La función numero_primo, permite determinar si un número es primo o no.
#
def numero_primo(numero):
i=2
es_primo=True
while ((i<numero) and (es_primo)):
Curso: Telemática
if numero % i == 0:
es_primo=False
else :
i=i+1
return es_primo
serverPort =12444
#Se instancia el servidor TCP
serverSocket = socket(AF_INET,SOCK_STREAM)
#Se define el puerto del servidor
[Link](('',serverPort))
#Servidor en modo escucha
[Link](1)
print("El servidor está listo para recibir peticiones: ")
while 1:
#Se extrae la información del puerto y la dirección ip del servidor
conSocket, addr = [Link]()
print("Recibiendo mensajes desde el cliente", addr)
#Obtiene la información extraida del cliente
msg= [Link](1024)
n= int(msg)
new_msg="NO";
if numero_primo(n) is True:
new_msg ="SI";
[Link](new_msg.encode('utf-8'))
Nuevamente, ejecute la siguiente instrucción
python Server_TCP_Primos.py
Tal y como se observa en la figura 18.
Curso: Telemática
Figura 18. Ejecución servidor socket TCP para calcular si un número es primo
Posteriormente, digite el siguiente código para el cliente.
Client_TCP_Primos
#Importa las librerias del sockets
from socket import*
#Se define la dirección ip a donde se va a apuntar al servidor
servername ="localhost"
#Se define el puerto por donde escucha el servidor
serverport=12444
#Se establece la instancia del cliente sockets
clienteSocket= socket(AF_INET,SOCK_STREAM)
#Se establece la conexión con el servidor
[Link]((servername,serverport))
#Se solicita al cliente que escriba un mensaje
msg=input("Escriba un número ")
#Se envia el mensaje al servidor con formato utf-8
[Link]([Link]('utf-8'))
#Se obtiene mensaje cambiado por el servidor
msg_modified=[Link](1024)
#se imprime el mensaje modificado por el servidor
print(msg, msg_modified, " es primo")
#Se cierra la conexion
[Link]()
Curso: Telemática
Ejecute la siguiente línea de comando.
python Client_TCP_Primos.py
Al final tendrá el resultado como se observa en la figura 19.
Figura 19. Ejecución del cliente TCP para calcular los números primos.
Curso: Telemática
ACTIVIDADES A DESARROLLAR
A. PROTOCOLO TCP
En los siguientes ejercicios, utilice la arquitectura cliente/servidor con el protocolo TCP.
Los datos los debe pedir el cliente TCP y el servidor TCP ejecutará y almacenará el
algoritmo. Finalmente el servidor TCP le devolverá la respuesta al cliente TCP. Utilice
dos máquinas, puede ser una virtual y otra física, ambas físicas o ambas virtuales. En
una máquina ejecutará el cliente y en la otra el servidor. En la máquina del cliente TCP
inicie Wireshark antes de ejecutar el respectivo script y realice el análisis de la trama
TCP capturada como se muestra en esta guía.
1. Una agencia de apuestas desea diseñar un sistema que pueda hacer las siguientes
operaciones:
El sistema debe pedir el número a jugar (puede ser de 3 o 4 cifras), la lotería con la que
quiere hacer la apuesta y el valor de la apuesta. El sistema debe consultar de acuerdo a
la fecha actual qué loterías están activas para el día en que el cliente hace la apuesta.
Cuando el cliente digite el número, la lotería y el valor, el sistema del cliente debe hacer
una solicitud al servidor y verificar que la apuesta no haya superado el tope. El tope de
apuesta es definido desde el servidor. El cliente al final del día podrá consultar:
Cuál fue el número más jugado de acuerdo a la lotería.
El monto total recaudado de acuerdo a todas las apuestas.
El monto recaudado por loterías.
El número menos jugado.
2. La Registraduría Nacional del Estado Civil de Colombia, lo ha contratado a usted para
que resuelva el siguiente problema:
Se desea desarrollar un sistema que permita capturar desde un cliente su identificación
y éste a su vez haga una solicitud a un servidor para que consulte si es jurado de
votación, en el caso afirmativo debe decir la mesa en donde el ciudadano debe asistir
como jurado. De igual forma, el sistema del lado del cliente debe permitir consultar en
qué lugar puede votar un ciudadano de acuerdo a su cédula.
Para resolver este problema debe implementar una base de datos o en su defecto unos
archivos planos para hacer las consultas en el servidor.
Curso: Telemática
B. PROTOCOLO UDP
3. Hacer un programa que calcule el factorial de un número entero positivo.
Realizar el anterior ejercicio utilizando la arquitectura cliente/servidor con el protocolo
UDP. El cliente UDP debe pedir el valor de n, el servidor UDP ejecutará el algoritmo que
calcula n factorial y devolverá la respuesta al cliente UDP. Inicie Wireshark en la
máquina del cliente UDP, antes de ejecutar el script y realice el análisis de la trama UDP
capturada como se muestra en esta guía.
Referencias
Kurose, J., & Ross, K. (2017). Computer networks: A top down approach featuring the
internet. Pearson Addison Wesley.
Python [Link]
Wireshark [Link]