Está en la página 1de 10

Computadores y Comunicaciones

Prctica de Laboratorio: Diseo de


una aplicacin basada en el modelo
cliente-servidor
Julin Viejo Corts

Jorge Juan Chico

Marzo 2009
Computadores y Comunicaciones Prctica Modelo Cliente-Servidor

ndice de contenidos

1. Introduccin....................................................................................................2
2. Ejemplo 1: Aplicacin bsica..........................................................................2
3. Ejemplo 2: Aplicacin interactiva...................................................................3
4. Anexos: Cdigos de los ejemplos....................................................................4
4.1. Cdigos del Ejemplo 1..............................................................................4
4.1.1. Servidor bsico...............................................................................................4
4.1.2. Cliente bsico.................................................................................................5
4.2. Cdigos del Ejemplo 2..............................................................................6
4.2.1. Servidor interactivo........................................................................................6
4.2.2. Cliente interactivo..........................................................................................7

1
Computadores y Comunicaciones Prctica Modelo Cliente-Servidor

1. Introduccin
Esta prctica de laboratorio tiene como objetivo mostrar el funcionamiento de
las aplicaciones basadas en el modelo cliente-servidor.
Para ello, se ha desarrollado una serie de ejemplos sobre un sistema
Ubuntu/Linux, en concreto:
Ejemplo 1: Aplicacin bsica.
Ejemplo 2: Aplicacin interactiva.
En todos los casos, se proporcionar a los alumnos el cdigo fuente de los
programas, de forma que el trabajo a realizar consiste en completar los
diferentes apartados que se plantean. Los ejemplos propuestos estn
implementados utilizando el lenguaje de programacin Python.
En principio no es necesario instalar ningn programa, aunque s ser
necesario utilizar un editor de texto plano (nano, gedit, etc.) para la
visualizacin del contenido de los archivos.

2. Ejemplo 1: Aplicacin bsica


En este primer ejemplo vamos a partir de dos programas escritos en lenguaje
Python, teniendo los alumnos que realizar las siguientes tareas:
1. Descargar desde la pgina web de la asignatura el fichero comprimido
ejemplos_c_s.zip.
2. Descomprimir el contenido del fichero .zip dentro de la carpeta personal
(/home/curso).
3. Abrir un terminal y entrar dentro de la carpeta c_s_basico:
$ cd ejemplos_c_s/c_s_basico
4. Analizar los cdigos proporcionados, leyendo y comprendiendo los
comentarios. Para visualizar estos cdigos usar un editor de texto:
$ gedit servidor_basico.py cliente_basico.py
5. Ejecutar las aplicaciones servidor y cliente:
Primero, lanzar el servidor:
$ python servidor_basico.py 9000
Segundo, lanzar en un nuevo terminal el cliente:
$ python cliente_basico.py localhost 9000
6. Comprobar el correcto funcionamiento de la aplicacin leyendo los
mensajes que se imprimen en los terminales.
A continuacin, responder brevemente a las siguientes cuestiones:
1. Dentro de la aplicacin servidor, con la llamada a la funcin
listening_socket.listen, en qu estado solicitamos que se abra el

2
Computadores y Comunicaciones Prctica Modelo Cliente-Servidor

conector (socket) creado con la llamada a esta funcin?


2. Dentro de la aplicacin cliente, con la llamada a la funcin
connection_socket.connect, con quin se est intentando establecer
una conexin y en qu puerto?
3. Con la llamada a la funcin listening_socket.accept, dentro de la
aplicacin servidor, qu estamos aceptando? qu se ha establecido?
4. Qu ocurre si ejecutamos antes el cliente que el servidor?

3. Ejemplo 2: Aplicacin interactiva


En este segundo ejemplo, partiendo de la aplicacin del ejemplo 1, vamos a
mejorar los dos programas para que tanto el cliente como el servidor puedan
interaccionar (intercambiar mensajes de texto). Los alumnos realizarn las
siguientes tareas:
1. Estando dentro del directorio c_s_basico, moverse al directorio
c_s_interactivo:
$ cd ../c_s_interactivo
2. Analizar los cdigos proporcionados, leyendo y comprendiendo los
comentarios. Para visualizar estos cdigos usar un editor de texto:
$ gedit servidor_interactivo.py cliente_interactivo.py
3. Ejecutar las aplicaciones servidor y cliente:
Primero, lanzar el servidor:
$ python servidor_interactivo.py 9000
Segundo, lanzar en un nuevo terminal el cliente:
$ python cliente_interactivo.py localhost 9000
4. Escribir mensajes tanto en la parte del cliente como en la del servidor y
comprobar el correcto funcionamiento de la aplicacin.
A continuacin, responder brevemente a las siguientes cuestiones:
1. Qu llamadas deben hacerse desde la lnea de comando para
conectarse a otra mquina que no sea el localhost?
2. Conctese a la mquina de su compaero e interaccione con l.

3
Computadores y Comunicaciones Prctica Modelo Cliente-Servidor

4. Anexos: Cdigos de los ejemplos


Estos cdigos estn basados inicialmente en ejemplos de "Network
programming" por Paul Harrison.

4.1. Cdigos del Ejemplo 1

4.1.1. Servidor bsico

import sys, os
from socket import *
from time import *

# Establece el puerto en el que va a escuchar el servidor (ser un


# parmetro pasado por la lnea de comandos).
if(len(sys.argv) > 1):
port = int(sys.argv[1])
else:
print "Uso: python servidor_basico server_port"
sys.exit(1)

# Crea un socket para escuchar en espera de nuevas conexiones.


listening_socket = socket(AF_INET,SOCK_STREAM)

# Conecta el socket a un puerto en el que escuchar. Slo root puede


# escuchar en puertos por debajo de 1024.
listening_socket.bind(('', port))

# Dice al socket que comience a escuchar. El argumento es el nmero


# mximo de conexiones permitidas. Slo se atiende una cada vez.
listening_socket.listen(1)

# Un socket que escucha slo sirve para escuchar. Cuando se establece una
# conexin se crea un nuevo socket para el intercambio de informacin.

while 1:
# Espera a que haya una conexin y la acepta.
accepted_socket, address = listening_socket.accept()

# Al aceptar una conexin se crea un nuevo socket de forma que el


# servidor puede seguir escuchando en el socket de escucha en espera
# de nuevas conexiones. En nuestro caso, se muestra un mensaje, se
# cierra la conexin y se espera una nueva conexin.

# Crea los ficheros asociados con el socket. Permite leer y escribir


# del socket como si de un fichero se tratase.
incoming_stream = accepted_socket.makefile("rt")
outgoing_stream = accepted_socket.makefile("wt")

# Crea un texto con la hora local.


local_time = ctime()

4
Computadores y Comunicaciones Prctica Modelo Cliente-Servidor

# Enva la hora al cliente


outgoing_stream.write(local_time + "\n")

# Deja un registro de la conexin del cliente


print "Conexin desde", address, "en", local_time

# Cierra la conexin y repite el bucle


incoming_stream.close()
outgoing_stream.close()
accepted_socket.close()

4.1.2. Cliente bsico

import sys, os
from socket import *

# Establece el nombre y el puerto del servidor (sern dos parmetros


# pasados por la lnea de comandos).
if(len(sys.argv) > 2):
server_name=sys.argv[1]
server_port = int(sys.argv[2])
else:
print "Uso: python cliente_basico server_name server_port"
sys.exit(1)

# Obtiene la direccin IP correspondiente al servidor.


server_address = gethostbyname(server_name)

# Crea un socket.
connection_socket = socket(AF_INET,SOCK_STREAM)

# Conecta el socket al servidor.


connection_socket.connect((server_address, server_port))

# Crea los ficheros asociados con el socket. Permite leer y escribir del
# socket como si de un fichero se tratase.
incoming_stream = connection_socket.makefile("rt")
outgoing_stream = connection_socket.makefile("wt")

# Ahora el cliente puede comunicarse con el servidor.


# Lee la hora y la imprime en la salida estndar (monitor).
print incoming_stream.read()

# Cierra la conexin y termina


incoming_stream.close()
outgoing_stream.close()
connection_socket.close()

5
Computadores y Comunicaciones Prctica Modelo Cliente-Servidor

4.2. Cdigos del Ejemplo 2

4.2.1. Servidor interactivo

import sys, os
from socket import *

# Establece el puerto en el que va a escuchar el servidor (ser un


# parmetro pasado por la lnea de comandos).
if(len(sys.argv) > 1):
port = int(sys.argv[1])
else:
print "Uso: python servidor_interactivo server_port"
sys.exit(1)

# Crea un socket para escuchar en espera de nuevas conexiones.


listening_socket = socket(AF_INET,SOCK_STREAM)

# Conecta el socket a un puerto en el que escuchar. Slo root puede


# escuchar en puertos por debajo de 1024.
listening_socket.bind(('', port))

# Dice al socket que comience a escuchar. El argumento es el nmero mximo


# de conexiones permitidas. Slo se atiende una cada vez.
listening_socket.listen(1)

# Un socket que escucha slo sirve para escuchar.


# Espera a que haya una conexin y la acepta.
# Cuando se establece una conexin se crea un nuevo socket para el
# intercambio de informacin.
accepted_socket, address = listening_socket.accept()

# El actual proceso se divide en dos:


# 1. Proceso padre: se encarga de leer los mensajes procedentes del cliente
# y de imprimirlos en pantalla
# 2. Proceso hijo: recoge mensajes de la entrada estndar y los enva al
# cliente
pid = os.fork()

if pid != 0:
# Entrando en el proceso padre
# Cerrar el socket de escucha
listening_socket.close()

# Permite leer del socket como si de un fichero se tratase.


incoming_stream = accepted_socket.makefile("rt")
print "El servidor acepta mensajes del cliente"

# Se entra en un bucle: cada vez que el cliente enva un mensaje lo


# imprimimos
# Si el mensaje es salir el cliente quiere desconectarse por lo que
# el servidor no aceptar ms mensajes
while True:

6
Computadores y Comunicaciones Prctica Modelo Cliente-Servidor

msg = incoming_stream.readline()
print msg
if msg == "salir\n":
break

# Se cierran los sockets


incoming_stream.close()
accepted_socket.close()

print "Cliente desconectado. Si no est desconectado escriba salir"


os.waitpid(pid, 0)
else:
# Entrando en el proceso hijo
# Cerrar el socket de escucha
listening_socket.close()

# Permite escribir en el socket como si de un fichero se tratase.


outgoing_stream = accepted_socket.makefile("wt")
print "El servidor permite mandar mensajes al cliente"

# Se entra en un bucle: se lee de la entrada estndar (teclado) los


# mensajes y se envan al cliente. Para desconectar escribimos salir
while True:
msg = raw_input()
outgoing_stream.write(msg + "\n")
outgoing_stream.flush()
if msg == "salir":
break

# Se cierran los sockets


outgoing_stream.close()
accepted_socket.close()
# Fin del proceso hijo
sys.exit(0)

4.2.2. Cliente interactivo

import sys, os
from socket import *

# Establece el nombre y el puerto del servidor (sern dos parmetros


# pasados por la lnea de comandos).
if(len(sys.argv) > 2):
server_name=sys.argv[1]
server_port = int(sys.argv[2])
else:
print "Uso: python cliente_interactivo server_name server_port"
sys.exit(1)

# Obtiene la direccin IP correspondiente al servidor.


server_address = gethostbyname(server_name)

# Crea un socket.

7
Computadores y Comunicaciones Prctica Modelo Cliente-Servidor

connection_socket = socket(AF_INET,SOCK_STREAM)

# Conecta el socket al servidor.


connection_socket.connect((server_address, server_port))

# El actual proceso se divide en dos:


# 1. Proceso padre: se encarga de leer los mensajes procedentes del
# servidor y de imprimirlos en pantalla
# 2. Proceso hijo: recoge mensajes de la entrada estndar y los enva al
# servidor
pid = os.fork()

if pid != 0:
# Entrando en el proceso padre
# Permite leer del socket como si de un fichero se tratase.
incoming_stream = connection_socket.makefile("rt")
print "El cliente acepta mensajes del servidor"

# Se entra en un bucle: cada vez que el servidor enva un mensaje lo


# imprimimos
# Si el mensaje es salir el servidor quiere desconectarse por lo que
# el cliente no aceptar ms mensajes
while True:
msg = incoming_stream.readline()
print msg
if msg == "salir\n":
break

# Se cierran los sockets


incoming_stream.close()
connection_socket.close()

print "Servidor desconectado. Si no est desconectado escriba salir"

os.waitpid(pid, 0)
else:
# Entrando en el proceso hijo
# Permite escribir en el socket como si de un fichero se tratase.
outgoing_stream = connection_socket.makefile("wt")
print "El cliente permite mandar mensajes al servidor"

# Se entra en un bucle: se lee de la entrada estndar (teclado) los


# mensajes y se envan al servidor. Para desconectar escribimos salir
while True:
msg = raw_input()
outgoing_stream.write(msg + "\n")
outgoing_stream.flush()
if msg == "salir":
break

# Se cierran los sockets .


outgoing_stream.close()
connection_socket.close()
# Fin del proceso hijo
sys.exit(0)

También podría gustarte