Está en la página 1de 8

Simple programa Cliente/Servidor (socket) en

python
By Diego Caraballo | 20:275 Comentarios

En la entrada de hoy veremos un simple ejemplo de un programa cliente/servidor utilizando


elmódulo socket en python. El módulo socket (canal de comunicación) es utilizado para
comunicar un programa cliente con un programa servidor en una red (también se puede
utilizar en el mismo equipo).

Los socket se pueden configurar para que actúen como un servidor y así poder escuchar
los mensajes entrantes, o conectarse a otras aplicaciones como clientes. Luego de que
ambos extremos de un socket TCP/IP están conectados, la comunicación es bidireccional.

Estas primeros ejemplos que explico, fueron creados en "localhost" en un PC con sistema
Linux (Ubuntu).

Cliente - Servidor

Creando un programa Servidor

Este sencillo código de ejemplo (Servidor.py), recibe mensajes entrantes y los ecos de vuelta
al remitente. Esto se hace creando un socket TCP/IP:
?

1
#!/usr/bin/python
2 # -*- coding: utf-8 -*-
3
4 # Programa Servidor
5 # www.pythondiario.com
6
7 import socket
8 import sys
9
# Creando el socket TCP/IP
10 sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
11

Luego el método bind() es utilizado para asociar un socket a una dirección de servidor. En
este caso, la dirección es un localhost (dirección actual) y el número de puerto es 10000.

1 # Enlace de socket y puerto


2 server_address = ('localhost', 10000)
3 print >>sys.stderr, 'empezando a levantar %s puerto %s' % server_address
4 sock.bind(server_address)

El método accept() acepta una conexión entrante (un cliente) y el método listen() pone al
socket en modo servidor.

1 # Escuchando conexiones entrantes


2 sock.listen(1)
3
4 while True:
5 # Esperando conexion
6 print >>sys.stderr, 'Esperando para conectarse'
connection, client_address = sock.accept()
7

El método accept() nos devuelve una conexión abierta entre el servidor y el cliente, junto
con la dirección del cliente. Los datos de la conexión se leen con el método recv() y se
transmiten con el método sendall().

1 while True:
2 # Esperando conexion
3 print >>sys.stderr, 'Esperando para conectarse'
connection, client_address = sock.accept()
4
5 try:
6 print >>sys.stderr, 'concexion desde', client_address
7
8 # Recibe los datos en trozos y reetransmite
9 while True:
data = connection.recv(19)
10 print >>sys.stderr, 'recibido "%s"' % data
11 if data:
12 print >>sys.stderr, 'enviando mensaje de vuelta al cliente'
13 connection.sendall(data)
14 else:
print >>sys.stderr, 'no hay mas datos', client_address
15 break
16
17 finally:
18 # Cerrando conexion
19 connection.close()
20
21
22

Cuando se termina la comunicación con un cliente, la conexión debe ser cerrada con
el método close(). Nuestro ejemplo utiliza try:finally para asegurar que la conexión sea
cerrada igual en caso de un error.

Creando un programa Cliente

El código para el programa cliente (Cliente.py) utiliza el socket diferente a como lo hace
elServidor. En lugar de unirse a un puerto para escuchar conexiones, utiliza el método
connect()para fijar una conexión remota.

1 #!/usr/bin/python
2 # -*- coding: utf-8 -*-
3
# Programa Cliente
4 # www.pythondiario.com
5
6 import socket
7 import sys
8
9 # Creando un socket TCP/IP
10 sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
11
# Conecta el socket en el puerto cuando el servidor esté escuchando
12 server_address = ('localhost', 10000)
13 print >>sys.stderr, 'conectando a %s puerto %s' % server_address
14 sock.connect(server_address)
15
16

Después que la conexión esté establecida, la información puede ser enviada con el método
sendall() y recibida con el método recv(), igual que el servidor.

1
2 try:
3
4 # Enviando datos
5 message = 'Este es el mensaje. Se repitio.'
print >>sys.stderr, 'enviando "%s"' % message
6
sock.sendall(message)
7
8 # Buscando respuesta
9 amount_received = 0
10 amount_expected = len(message)
11
12 while amount_received < amount_expected:
data = sock.recv(19)
13 amount_received += len(data)
14 print >>sys.stderr, 'recibiendo "%s"' % data
15
16 finally:
17 print >>sys.stderr, 'cerrando socket'
18 sock.close()
19
Finalmente, cuando el mensaje es enviado, y la copia recibida, la conexión se cierra para
dejar libre el puerto.

Diagrama de nuestro programa Cliente - Servidor


Diagrama Cliente/Servidor

Corriendo nuestros programas Servidor.py y Cliente.py

Ejecutaremos los programas en dos ventanas diferentes para que puedan comunicarse entre
si. Esta es la salida impresa del Servidor:
Salida impresa del Servidor

Salida impresa del programa Cliente:


Salida impresa del Cliente

Prueba de comunicación con dos equipos diferentes

Estuve realizando algunas pruebas con 2 computadoras virtuales diferentes (una


con Windows XP y otra con Windows 7).

El programa servidor lo corrí en la PC virtual con Windows XP y lo único que cambié en el


código de Servidor.py fue el "localhost" por "" (se deja vacío).

1 # Enlace de socket y puerto


2 server_address = ('', 10000)
3 print >>sys.stderr, 'empezando a levantar %s puerto %s' % server_address
4 sock.bind(server_address)
El programa Cliente.py lo corrí en la PC virtual con Windows 7 y lo único que le modifique
fue el "localhost" por la dirección IP del PC con Windows XP (Servidor):

1 # Conecta el socket en el puerto cuando el servidor esté escuchando


2 server_address = ('xxx.xxx.xxx.xxx', 10000)
3 print >>sys.stderr, 'conectando a %s puerto %s' % server_address
4 sock.connect(server_address)

Luego hice las pruebas de forma inversa. El PC con Windows 7 actuó como Servidor y el PC
con Windows XP funcionó como Cliente.

Las pruebas en ambos casos funcionaron correctamente.

Espero esta entrada sea de ayuda para iniciarse con los socket en python. Cualquier duda
o sugerencia pueden dejarlas al final de la entrada.

Fuente del material: http://pymotw.com/2/socket/tcp.html

También podría gustarte