Sunteți pe pagina 1din 49

Herramientas y Lenguajes de Programacin o

Coromoto Len Hernndez o a 1,5 crditos e Universidad de La Laguna Programa de Doctorado de F sica e Informtica a Dpto. de Estad stica, I.O. y Computacin o 2006-2007

Resumen El curso Herramientas y Lenguajes de Programacin del programa de doctorado de o F sica e Informtica est clasicado como metodolgico (optativo). La Figura 1 muestra a a o los distintos itinerarios que se pueden seguir en el programa de doctorado.

Figura 1: Itinerarios del Programa de Doctorado El curso est dividido en tres partes. Este material cubre la parte del curso relacionada a con la manipulacin de herramientas informticas y el desarrollo de aplicaciones. o a

Indice general
1. Introduccin o 1.1. Desarrollo de aplicaciones Informticas . . . . . a 1.2. Herramientas . . . . . . . . . . . . . . . . . . . 1.2.1. Proceso de Compilacin . . . . . . . . . o 1.2.2. Compilacin de programas formados por o 1.2.3. Creacin de Librer o as . . . . . . . . . . 1.2.4. Documentacin . . . . . . . . . . . . . . o 1.3. Lenguajes de Programacin . . . . . . . . . . . o 2 . 2 . 3 . 4 . 5 . 6 . 8 . 11

. . . . . . . . . . . . . . . . . . . . . . . . . . . varios mdulos o . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

2. Programas Java: Aplicaciones 14 2.1. Ejemplo de aplicacin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14 o 2.2. Ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15 3. Programas Java: applets 17 3.1. Ejemplo de applet . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17 3.2. Ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19 4. Creacin de Threads o 20 4.1. La clase Thread . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20 4.2. La interfaz Runnable . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21 4.3. Ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21 5. Sincronizacin de Threads o 23 5.1. Exclusin mutua y secuencializacin . . . . . . . . . . . . . . . . . . . . . . 23 o o 5.2. Ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24 6. Direcciones IP y Nombres de Dominio 25 6.1. La clase InetAddress . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25 6.2. Ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26 7. Las 7.1. 7.2. 7.3. clases Java DatagramPacket y Introduccin . . . . . . . . . . . o La clase DatagramPacket . . . La clase DatagramSocket . . . DatagramSocket . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1 28 28 29 30

Herramientas y Lenguajes de Programacin 06-07 o

7.4. Ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31 8. Las clases Java Socket y ServerSocket 8.1. Introduccin . . . . . . . . . . . . . . . . . . . . . . o 8.2. Sockets . . . . . . . . . . . . . . . . . . . . . . . . 8.2.1. La clase Socket . . . . . . . . . . . . . . . 8.2.2. La clase ServerSocket . . . . . . . . . . . 8.3. La clase Thread y la implementacin de servidores o 8.4. Ejercicios . . . . . . . . . . . . . . . . . . . . . . . 8.5. Cdigos Fuente del Servidor de chistes iterativo . . o 8.6. Cdigos Fuente del Servidor de chistes concurrente o . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34 34 35 36 38 39 40 42 45

Cap tulo 1

Introduccin o
El principal objetivo de est parte del curso de doctorado es dotar al alumno de las a habilidades necesarias para la manipulacin de herramientas informticas que le permitan o a realizar una labor investigadora ecaz. En el desarrollo de un proyecto informtico uno de los aspectos ms importantes es a a la eleccin del lenguaje ms apropiado para su implementacin y las herramientas a utio a o lizar. Existen mltiples herramientas informticas y mltiples lenguajes de programacin u a u o dependiendo del rea de estudio. Una vez elegido el lenguaje, se ha de recabar informacin a o sobre las herramientas disponibles y realizar un estudio acerca de cul se adapta mejor a a las necesidades del proyecto a realizar. As pues, es necesario iniciar al alumnado en el desarrollo sistemtico y ordenado de aplicaciones informticas integradas en proyectos de a a investigacin. En este curso, se especican de forma genrica las fases que componen el o e desarrollo e implementacin de una aplicacin informtica y se formalizan las mismas con o o a ejemplos concretos de realizacin. o Los objetivos concretos del curso son: Manejar los fundamentos bsicos del sistema operativo UNIX (Linux). a Conocer las herramientas informticas UNIX (Linux) fundamentales para el desaa rrollo de aplicaciones. Comprender los principios bsicos de la programacin imperativa, y oritentada a a o objetos. Reconocer la importacia de la generacin de documentacin que acompaa a todo o o n proyecto informtico. a Comprender como disear algoritmos ecientes utilizando distintas tcnicas algor n e tmicas.

1.1.

Desarrollo de aplicaciones Informticas a

En este apartado se expone de forma escueta cules son las partes que constituyen el a desarrollo de un programa, esto es, las etapas de desarrollo de software. 3

Herramientas y Lenguajes de Programacin 06-07 o

Figura 1.1: Etapas del desarrollo de software

Las etapas de desarrollo de software se pueden resumir en: 1. Disear una solucin, proponiendo un algoritmo. n o 2. Traduccir la solucin a pseudocdigo. o o 3. Implementar un programa en un lenguaje de programacin (en el caso que estudiao remos Java). 4. Compilar el programa. 5. Realizar pruebas de ejecucin. o Aunque las etapas se presentan de forma secuencial, es habitual cometer errores que provoquen el tener que regresar a fases anteriores. El esquema que se muestra en la Figura 1.1 es vlido para programas no demasiado complejos. Para los grandes proyectos a informticos exite un conjunto de tcnicas de desarrollo que pueden estudiarse en cualquier a e libro de Ingenier del Software, por ejemplo, R.S. Pressman, Ingenier del Software: Un a a enfoque Prtico, McGraw-Hill, 4 edicin, 1998. ISBN 84-481-1186-9. a o

1.2.

Herramientas

En el desarrollo de un proyecto informtico un aspecto importante es qu tipo de hea e rramientas se han de utilizar y el lenguaje ms apropiado para su implementacin. Existen a o

Herramientas y Lenguajes de Programacin 06-07 o

mltiples herramientas informticas y mltiples lenguajes de programacin dependiendo u a u o del rea de estudio. a El sistema operativo elegido para realizar los ejercicios prctico es este curso es Unix a (Linux), debido a la diponibilidad de gran cantidad de herramientas que facilitan al programador el desarrollo y mantenimiento de sus programas. En este ep grafe, se har un a repaso de algunas de la principales herramientas que existen en el entorno Unix para el desarrollo de programas en el lenguaje de programacin Java. Estas herramientas incluo yen los compiladores - en los cuales se pueden encontrar diferencias segn la versin Unix u o utilizada-, los intrpretes de la mquina virtual de Java (l e a nea de comandos - stand-alone o herramientas de visualizacin - appletviewer ), la creacin de paquetes o bibliotecas, etc. o o

1.2.1.

Proceso de Compilacin o

Un traductor es un programa informtico que traduce de un lenguaje fuente a un a lenguaje objeto. Un compilador es un traductor en el que el lenguaje fuente es un Lenguaje de Programacin de Alto Nivel, y el lenguaje objeto es Lenguaje Ensamblador o Lenguaje Mquina. o a El proceso de traduccin que tiene que realizar un compilador, se puede dividir en los o siguientes pasos: Preprocesamiento Compilacin (propiamente dicho) y Optimizacin o o Generacin de Cdigo Objeto o o Enlace ( linker ) No es uno de los objetivos de este curso el estudiar en profundidad el proceso de compilacin sino utilizar las herramientas disponibles para llevarlo a cabo. Para un estudio en o detalle de los compiladores recomendamos el libro: A. Aho, R. Sethi, J. Ullman, Compiladores. Principios, Tcnicas y Herramientas, Adisson-Wesley Iberoamericana, ISBN 0-201e 62903-8 La Figura 1.2 muestra el conjunto de herramientas que proporciona el paquete GCC de GNU para los compiladores de los lenguajes C y C++. El prepocesador ( cpp ) se invoca con el comando: g++ programa.C -E -o programa.i El compilador propiamente dicho ( comp ) se llama con la orden: g++ programa.C -S -o programa.s La llamada al ensamblador ( as ) utiliza la opcin -c: o g++ programa.C -c -o programa.o

Herramientas y Lenguajes de Programacin 06-07 o

Figura 1.2: Herramientas del compilador de GCC

El editor de carga y enlace (ld) se invoca automticamente sin especicar ninguna a opcin: o g++ programa.C Se obtiene el chero a.out que ya es ejecutable. Los cheros intermedios generados se almacenan en /tmp y se borran cuando termina todo el proceso de compilacin. o En el caso de Java, se habla de un lenguaje de programacin y de una plataforma o de ejecucin. Como lenguaje de programacin de alto nivel se ha de destacar que es o o completamente orientado a objetos y tiene denida una sintaxis y una semntica. La a plataforma de ejecucin de Java est compuesta por: o a La Mquina Virtual de Java (Java Virtual Machine - JVM) a Los APIs (Application Programming Interfaces - Paquetes)

1.2.2.

Compilacin de programas formados por varios mdulos o o

Consideremos la divisin de la implementacin de un problema C/C++ en dos cheros: o o programa1.cc y programa2.cc. Segn se muestra en la Figura 1.3, el primer paso consiste u en editar dichos cheros (con el editor vi, por ejemplo). A continuacin, la orden que se o deber emitir para generar la aplicacin es: a o

Herramientas y Lenguajes de Programacin 06-07 o

Figura 1.3: Compilacin de varios mdulos separados o o

g++ programa1.c programa2.c Se ha de tener en cuenta, que la llamada al enlazador (linker) se realiza de forma automtica. Por lo tanto, los dos cheros intermedios, programa1.o y programa2.o se a borraran al nalizar la operacin. Si se quieren conservar ambos es necesario compilar con o los comandos: g++ -c programa1.c g++ -c programa2.c g++ programa1.o programa2.o La procedencia de los cheros que aporta el sistema operativo al proceso de compilacin o es la siguiente: Ficheros de Cabecera - directorio /usr/include Libreras - directorios /lib, /usr/lib

1.2.3.

Creacin de Librer o as

La creacin de librer (o bibliotecas) aporta modularidad y portabilidad a los proo as gramas. Una librer es un chero que est compuesto por una coleccin de otros cheros llaa a o mados miembros de la librer La estructura de una librer posibilita la extraccin de a. a o

Herramientas y Lenguajes de Programacin 06-07 o

sus miembros. Cuando se aade un chero a una librer los datos de ste y su informan a, e cin administrativa (permisos, fechas, propietario, grupo, etc.) se introduce en l. Para o e una descripcin detallada de las opciones de esta herrmienta visite la pgina de manual o a (man ar). Las funciones bsicas de ar son: crear, modicar y extraer miembros. a ar [-] opciones [miembro] librera [ficheros] Entre las opciones se deben distinguir aquellas que son obligatorias y los modicadores. Cuando se emite una orden ar es necesario que haya una obligatoria y slo una. o Los paquetes Java agrupan las clases en librer (bibliotecas). Los paquetes Java se as utilizan de forma similar a como se utilizan las librer en C++, slo que en Java se as o agrupan clases y/o interfaces. En los paquetes las clases son unicas, comparadas con las de otros paquetes, y permi ten controlar el acceso. Esto es, los paquetes proporcionan una forma de ocultar clases, evitando que otros programas o paquetes accedan a clases que son de uso exclusivo de una aplicacin determinada. o Los paquetes se declaran utilizando la palabra reservada package seguida del nombre del paquete. Esta sentencia debe estar al comienzo del chero fuente. Concretamente debe ser la primera sentencia ejecutable del cdigo Java, excluyendo, los comentarios y espacios o en blanco. Por ejemplo:
package figuras; public class Circulo { . . . }

En este caso, el nombre del paquete es figuras. La clase Circulo se considera como parte del paquete. La inclusin de nuevas clases en el paquete es simple, se ha de colocar o la misma sentencia al comienzo de los cheros que contengan la declaracin de las clases. o Cada uno de los cheros que contengan clases pertenecientes a un mismo paquete, deben incluir la misma sentencia package, y solamente puede haber una sentencia package por chero. La sentencia package colocada el comienzo de un chero fuente afectar a todas a las clases que se declaren en ese chero. Se pueden referenciar paquetes precediendo con su nombre la clase que se quiere usar. Tambin se puede usar la palabra reservada import, si se van a colocar mltiples referencias e u a un mismo paquete. La sentencia import se utiliza para incluir una lista de paquetes en los que buscar una clase determinada, y su sintaxis es: import nombre_paquete.Nombre_Clase; Esta sentencia, o grupo de ellas, deben aparecer antes de cualquier declaracin de clase o en el cdigo fuente. o

Herramientas y Lenguajes de Programacin 06-07 o

1.2.4.

Documentacin o

La herramienta javadoc genera pginas HTML de documentacin del API a partir de a o cheros con cdigo fuente Java. o En la l nea de comandos se le puede pasar a javadoc una serie de paquetes o cheros Java para los que se desea generar documentacin. Se genera documentacin para el pao o quete especicado o para los cheros fuentes Java individuales que se listen en la l nea de comandos. Se genera un chero .html por cada chero .java que se encuentre. Tambin e se genera la jerarqu de clases (tree.html) y un a ndice con todos los miembros que ha detectado (AllNames.html). La utilidad javadoc extrae informacin de los siguiente elementos: o Paquetes Clases e interfaces pblicas u Mtodos pblicos y protegidos e u Datos pblicos y protegidos u Se puede aadir documentacin para todos estos entes a travs de comentarios de n o e documentacin en el cdigo fuente. Estos comentarios pueden incluir marcas HTML. Un o o comentario de documentacin est formado por todos los caracteres incluidos entre /** que o a indica el comienzo del comentario y */ que indica el nal. En todas las l neas intermedias los caracteres * a la izquierda se ignoran, y tambin todos los espacios y tabuladores que e precedan a ese carcter *. a
/** * Este es un comentario de documentacin o */

Se pueden incluir etiquetas HTML dentro de un comentario de documentacin, aunque o no deben utilizarse las etiquetas <h1>, <h2>,... o l neas horizontales <hr>, porque javadoc crea una estructura completa para el documento y estas marcas intereren con el formato general de ese documento. Cada comentario de documentacin puede incluir texto libre seguido de etiquetas de o documentacin. Estas etiquetas comienzan siempre con el signo @ y deben situarse al o principio de la l nea (tener en cuenta que todo lo que haya hasta el primer carcter * a se ignora) y todas las etiquetas con el mismo nombre deben agruparse juntas dentro del comentario de documentacin. o Marcas de documentacin de clases e interface o
@see nombre_de_clase

Aade un enlace a la clase especicada en la zona See Also. Por ejemplo: n

Herramientas y Lenguajes de Programacin 06-07 o

10

@see @see @see @see @see @see

java.lang.String String String#equals java.lang.Object#waint(int) Character#MAX_RADIX <a href="spec.html">Especif. Java</a>

Se utiliza el carcter # para separar el nombre de una clase del nombre de uno de a sus campos de datos, mtodos o constructores. e
@version texto-version

Aade una entrada Version. El texto no tiene que tener formato especial. n
@author texto-autor

Aade una entrada Author. El texto no tiene que tener formato especial. n
@since texto

Este texto no tiene una estructura especial. Se utiliza para indicar desde qu fecha e o desde qu versin se ha introducido el cambio o caracter e o stica que indica el texto.
@deprecated texto

Aade un comentario indicando que el mtodo est desautorizado y no deber utin e a a lizarse porque puede dejar de ser soportada por el API. La convencin que se sigue o es indicar en el texto la funcin o mtodo por quien se ha sustituido. Ejemplo de o e comentario de una clase:
/** * Clase que representa la figura geomtrica cilindro e * Por ejemplo: * <PRE> * Cilindro c = new Cilindro(1.0); * double d = c.volumen(); * </PRE> * * @see figuras.Circulo * @see figuras.ObjetoGeometrico * @version 1.5 14 Mar 04 * @author Coromoto Leon Hernandez */ public class Cilindro extends Circulo { . . . }

Herramientas y Lenguajes de Programacin 06-07 o Marcas de documentacin de campos de datos o

11

La unica marca especial que se puede incluir es la marca @see. Ejemplo de comentario de un campo de datos:
/** * El palo de bastos */ public static final int BASTOS = 1;

Marcas de documentacin de constructores y mtodos o e Pueden ser marcas @see y adems: a


@param parametro descripcion

Aade un parmetro a la seccin Parameters. La descripcin puede continuar en n a o o la l nea siguiente.


@return descripcion

Aade una seccin Return, que debe contener la descripcin del valor a devolver. n o o
@throws exception descripcion

Aade una entrada Throws, que contiene el nombre de la excepcin que puede ser n o lanzada por el mtodo. La excepcin estar enlazada con su clase en la documentae o a cin. o
@see nombre_de_clase

Aade un enlace a la clase en la zona See Also. n


@since texto

Indica desde qu fecha o desde qu versin se ha introducido el cambio o caracter e e o stica que indica el texto.
@deprecated texto

Indica que no deber utilizarse el mtodo, porque est desautorizado y puede dejar a e a de ser soportado por el API en cualquier momento. Ejemplo de comentario de un mtodo: e
/** * Devuelve el carcter de la posicin indicada entre a o * <tt>0</tt> y <tt>length()-1</tt> * @param indice La posicin del carcter a obtener o a * @return El carcter situado en la posicin a o

Herramientas y Lenguajes de Programacin 06-07 o

12

Figura 1.4: Evolucin de la metodolog de programacin o a o

* @exception StringIndexOutOfRangeException * Se prodcue cuando el indice no est en a * el rango <tt>0</tt> a <tt>length()-1</tt> */ public char charAt( int indice ) { . . . }

1.3.

Lenguajes de Programacin o

El debate en este caso se centra en la programacin orientada a objetos frente a la o programacin tradicional. La Figura 1.4 muestra la evolucin de la metodolog de la o o a programacin desde los primeros tiempos de la informtica hasta hoy. o a En la historia de la programacin ha habido varias evoluciones sucesivas. Una de las o principales fue la programacin estructurada, cuyo principio fundamental era dividir un o programa en subprogramas ms pequeos y fciles de resolver, hasta llegar a niveles de a n a complejidad elementales, siempre apoyndose en la idea de Qu debe hacer el programa?. a e Este mtodo de diseo, a pesar de haber dado resultados satisfactorios, tiene limitae n ciones. Algunas de ellas son: No favorece la reulitizacin del cdigo. o o Si en la gura anterior f n1 y f n2 fueran idnticas, este hecho seguramente pasar e a desapercibido y no se compartir una unica funcin f n. a o Si dos subprogramas comparten una misma funcin f n reutilizando as el cdigo que o o dene la misma, y ms adelante queremos modicar f n porque hay un cambio en a uno de los subprogramas que la utilizan, la modicacin afectar tambin al otro o a e subprograma, razn por la que ahora tendremos que realizar dos funciones. o Por lo tanto, se tiene que la programacin tradicional se desarrolla a partir de proceo dimientos y datos, sin delimitar qu procedimientos actan sobre qu datos. e u e El diseo orientado a objetos se interesa en primer lugar por los datos, a los que se n asocian posteriormente procedimientos. En este caso la idea principal es de qu trata el e

Herramientas y Lenguajes de Programacin 06-07 o

13

programa?. As que el desarrollo se organiza en torno a los datos y no a como se debe funcionar. En la programacin orientada a objetos, un programa es una coleccin de una sla o o o entidad bsica, el objeto, el cual combina los datos con los procedimientos que actan a u sobre ellos. Durante la ejecucin los objetos reciben y env mensajes a otros objetos o an para ejecutar las acciones requeridas. La programacin orientada a objetos se puede llevar a cabo con lenguajes convencionao les, pero esto exige al programador la construccin de los mecanismos de que disponen los o lenguajes orientados a objetos, tales como: objetos, clases, mtodos, mensajes, herencia. e etc.

Herramientas y Lenguajes de Programacin 06-07 o

14

Cap tulo 2

Programas Java: Aplicaciones


El objetivo de este ejercicio prctico es mostrar el modo de funcionamiento de los a distintos tipos de programas Java. En este caso se abordarn las aplicaciones. a

2.1.

Ejemplo de aplicacin o

El cdigo que aparece a continuacin implementa en Java la aplicacin que muestra o o o en la terminal la frase Hola Mundo en Java: 1 /** 2 * Applicacion Simple 3 */ 4 class AplicacionSimple { 5 public static void main(String[] args) { 6 System.out.println("Hola Mundo en Java"); 7 } 8 } El primer paso para manipular una aplicacin Java es compilarla ejecutando en la l o nea de comandos la instruccin o >javac AplicacionSimple.java Es importante que el nombre del chero que contiene el cdigo coincida exactamente o con el nombre de la clase que aparece en la l nea nmero 3. u Al realizar este paso se obtiene un chero AplicacionSimple.class. Para ejecutar la aplicacin escribimos en la l o nea de comandos >java AplicacionSimple y obtenemos el resultado que aparece en la gura 2.1. 15

Herramientas y Lenguajes de Programacin 06-07 o

16

Figura 2.1: Ejecucin de la aplicacin o o

2.2.

Ejercicios

1. Compile y ejecute el ejemplo de aplicacin. o 2. Escriba una aplicacin Java que: o Contemple la creacin de una clase (Clase1) que contengan un atributo entero o y mtodos para establecer y recuperar los valores de dicho atributo. e Denir una segunda clase (Clase2) con un atributo que es un objeto de la Clase1 y con un mtodo que establece diez valores diferentes en el atributo de e la Clase1. Denir una tercera clase (Clase3) con un atributo que es un objeto de la Clase1 y con un mtodo que recupera diez valores del atributo de la Clase1. e Finalmente, crear una clase de prueba donde se instancien objetos de las clases anteriores y se invoque a sus mtodos. e 3. Escriba la jerarqu de clases del programa que ha desarrollado. a 4. Dibuje una traza del ujo de ejecucin de la aplicacin. o o 5. Comente sus clases utilizando javadoc genere cheros de descripcin de su clase o similares a los de la documentacin de las API de Java. o En el documento de descripcin de la herramienta Javadoc puede encontrar la forma o de uso de las distintas etiquetas disponibles: @see, @author, @version, @param, @return (conexin a java.sun.com ) o Ejecute el comando javadoc desde la l nea de comandos sin ningn argumento y u obtendr una lista de las opciones con las que puede llamar a la herramienta. a

Herramientas y Lenguajes de Programacin 06-07 o

17

Ntese que para que aparezcan en el chero html los comentarios asociados a los o campos de datos privados, tiene que compilarlos con la opcin -private. o De la misma forma, para que aparezcan el autor y la versin, se han de utilizar las o opciones -author y -version.

Cap tulo 3

Programas Java: applets


El objetivo de esta prctica es mostrar el modo de funcionamiento de los distintos tipos a de programas Java. En esta prctica se abordarn los applets. a a

3.1.

Ejemplo de applet

El cdigo que aparece a continuacin muestra la implementacin en Java del programa o o o que muestra en la ventana principal del navegador la frase Hola Mundo en Java: /** * Applet Sencillo */ import java.applet.Applet; import java.awt.Graphics; public class AppletSimple extends Applet{ public void paint(Graphics g){ g.drawString("Hola Mundo en Java", 50, 25); } } El primer paso para manipular un applet Java es compilarlo ejecutando en la l nea de comandos la instruccin o >javac AppletSimple.java Al realizar este paso se obtiene una chero AppletSimple.class. El chero .class resultante de la compilacin, se ha de incrustar en un chero para o ser ejecutado por un navegador. En este caso las etiquetas a utilizar son <APPLET> y </APPLET>.

18

Herramientas y Lenguajes de Programacin 06-07 o

19

El siguiente cdigo html contine la estructura de la etiqueta para el ejemplo que nos o ocupa (est almacenado en un chero con nombre html.html). a
<html> <head> <title> Un applet simple </title> </head> <body> <p> A continuacin est la salida del programa o a </p> <applet code="AppletSimple.class" width="300" height="100"> No hay disponible un intrprete de Java e </applet> </body> </html>

Ntese que en el atributo asociado code de la etiqueta <APPLET> se ha especicado o AppletSimple.class y no AppletSimple.java.

Figura 3.1: Ejecucin del applet en un navegador o Finalmente, cuando se abre con un navegador el chero html.html se obtiene el resultado que se muestra en la gura 3.1. El paquete de desarrollo que proporciona SUN tambin ofrece una herramienta de e visualizacin. Para usarla se ha de ejecutar: o >appletviewer html.html La herramienta appletviewer slo muestra el applet. Ignora el cdigo html en el que o o est incrustado (vase la gura 3.2). a e

Herramientas y Lenguajes de Programacin 06-07 o

20

Figura 3.2: Ejecucin del applet con appletviewer o

3.2.

Ejercicios

1. Compile y ejecute el ejemplo de applet. 2. Implemente un applet que: Dena la misma jerarqu de clases que en la prctica anterior, pero en la que la a a Clase1 se denomine CampoTextoEntero y extienda a la clase java.awt.TextField, proporcionando mtodos para establecer y recuperar un valor entero en un came po de texto. Cree una clase de prueba que extienda a la clase java.awt.Applet, donde se instancien objetos de las clases denidas por usted y un objeto de la clase java.awt.Button. Para aadir las componentes al applet utilizar el mtodo n e add en el la implementacin del mtodo init del applet. o e Implemente los eventos de manera que cuando el usuario pulse el botn se invoo quen a los mtodos que permiten establecer y recuperar los diez valores del came po de texto. Para ello, la clase debe implementar la interfaz ActionListener que slo incluye al mtodo public void actionPerformed(ActionEvent e). o e Para registrar al applet como oyente del objeto botn utilizar el mtodo o e addActionListner. 3. Escriba la jerarqu de clases del applet que ha desarrollado. a 4. Dibuje una traza del ujo de ejecucin del applet. o

Cap tulo 4

Creacin de Threads o
El objetivo de esta prctica es introducir al uso de los threads (hilos) y trabajar con a las clases que permiten su creacin. o

4.1.

La clase Thread

Para crear y ejecutar un thread , en primer lugar, hay que denir una clase que extienda a la clase Thread. Esta clase debe sobreescribir el mtodo run(), que le dice al sistema la e tarea que debe ejecutar el thread .
class AClass extends Thread { ... public void run() { ... } }

En una clase cliente se crea un objeto thread . A estos objetos se les denomina objetos ejecutables. El mtodo start() le indica al sistema que el thread est listo para ejecutarse. e a
public class Client { ... public static void main(String [] args) { ... AClass ut = new AClass(); ... ut.start(); ... } }

21

Herramientas y Lenguajes de Programacin 06-07 o

22

4.2.

La interfaz Runnable

Para crear un thread para una clase que hereda de otra, es necesario implementar la interfaz Runnable. Para ello podemos seguir los siguientes pasos generales: Aadir en la declaracin de la clase que se va a implementar la interfaz Runnable: n o
public class AClass extends MotherClass implements Runnable

Declarar un objeto Thread en la clase destino. Por ejemplo, las siguientes sentencias declaran una instancia de la clase Thread, t, con valor inicial nulo:
private Thread t = null;

Por defecto, el valor inicial es nulo, as que la asignacin al valor nullno es necesaria. o Crear un thread (con el operador new) y ponerla en marcha llamando a su mtodo e start():
t = new Thread(this); //crear el thread t.start(); //poner en marcha el thread

El argumento this.en el constructor del thread es indispensable, puesto que especica que el mtodo run() de la clase actual es el que se debe llamar cuando se ejecute el e thread . El mtodo start() del thread provoca que el mtodo run() se ejecute. e e Implementar en el mtodo run() de la clase, la tarea que se quiere que ejecute el e thread .

4.3.

Ejercicios

1. Escriba una aplicacin Java que implemente lo siguiente: o Contemple la creacin de una clase (Mostrador) que contengan un atributo o entero y mtodos para establecer y recuperar los valores de dicho atributo. e Escriba una aplicacion Productor/Consumidor en la que se instancian dos objetos: uno de tipo Productor y otro de tipo Consumidor. Estos objetos son threads que se encargan uno de poner un valor y el otro de recogerlo de un objeto de tipo Mostrador.

Herramientas y Lenguajes de Programacin 06-07 o

23

Productor

Consumidor

Mostrador

Figura 4.1: Ejemplo del Productor/Consumidor

El Productor genera un entero entre 0 y 1000, lo almacena en el mostrador y lo imprime. El Consumidor al contrario, consume el entero del mostrador, que es exactamente el mismo objeto en el que el Productor coloca los enteros. As pues, el productor y el consumidor de este ejemplo comparten los datos a travs del objeto de tipo Mostrador (gura 8.3). e 2. Dibuje la jerarqu de clases que ha implementado. a 3. Dibuje el diagrama de ejecucin de la aplicacin (tiempo mtodo). o o e 4. Escriba un applet que implemente lo mismo que el ejercicio 1. 5. Dibuje la jerarqu de clases para el applet. a 6. Dibuje el diagrama de ejecucin del applet (tiempo mtodo). o e

Cap tulo 5

Sincronizacin de Threads o
El objetivo de esta prctica es trabajar con los principios bsicos de los threads (hilos): a a la sincronizacin y la secuencializacin. o o

5.1.

Exclusin mutua y secuencializacin o o

La programacin se vuelve un poco ms compleja cuando se tiene un programa con o a threads. Considrese la siguiente descripcin aparentemente sencilla: e o Los threads A y B comparten un dato, contador. El thread A efecta repetiu damente algunos clculos que producen un entero y lo coloca en el contador. a El thread B obtiene repetidamente el texto del contador y lo utiliza para sus propios clculos. a Cuando el programa est en ejecucin, el sistema alterna la ejecucin de A y B. La e o o forma en que ocurre esto var de un Sistema Operativo a otro y est completamente fuera a a del control del programador. Es posible que el sistema ejecute un thread hasta terminarlo, antes de iniciar el otro; que ejecute tres instrucciones de un thread antes de hacer lo mismo con una del otro, e incluso que deje un thread en medio de una instruccin, lo suspenda y empiece con el otro. o Una vez adevertido que es imposible suponer nada acerca del orden de ejecucin o de dos o ms threads, aparecen los siguientes escenarios: a 1. El thread A se ejecuta parcialmente en la actualizacin del contador y luego la ejecuo cin cambia a B. El resultado de B puede recibir basura cuando trata de inspeccionar o el contador. 2. El thread A escribe nueva informacin en el contador antes de que B inspeccione el o valor antiguo. Este ultimo se pierde. 3. El thread B recibe un valor y luego accede a contador de nuevo antes de que A haya generado un nuevo valor. Se utiliza dos veces el valor antiguo. 24

Herramientas y Lenguajes de Programacin 06-07 o

25

El escenario 1 requiere exclusin mutua, en que no permite que dos threads tengan o acceso simultneo al recurso compartido contador. Los escenarios 2 y 3 requieren secuena cializacin, en que cada thread debe esperar a que el otro termine de usar el recurso o compartido. Es importante sealar que estos escenarios son problemticos slo porque los threads A n a o y B tienen acceso al objeto contador. Si el cdigo que ejecutan A y B no hiciera referencia o a un objeto compartido, estos subprocesos podr ejecutarse en el orden que decida el an Sistema Operativo y dicho orden no tendr efecto en el resultado del programa. a La aplicacin PCTest.java contiene la denicin de una aplicacin Productor/Cono o o sumidor en la que se instancian dos objetos: uno de tipo Productor y otro de tipo Consumidor. Estos objetos son threads que se encargan uno de poner un valor y el otro de recogerlo de un objeto de tipo Mostrador. El Productor genera enteros entre 0 y 9, los almacena en el mostrador y los imprime. El Consumidor al contrario, consume todos los enteros del mostrador (que es exactamente el mismo objeto en el que el productor coloca los enteros) tan pronto como estn disponibles. As pues, el productor y el consumidor de a este ejemplo comparten los datos a travs del objeto de tipo Mostrador. e

5.2.

Ejercicios

1. Compile y ejecute la aplicacin Productor/Consumidor. o 2. Aada al cdigo de la aplicacin Productor/Consumidor las sentencias necesarias n o o para que los dos threads que se ejecutan pasen al estado de dormido durante un intervalo aleatorio de tiempo. Cambia el resultado de la ejecucin? Por qu? o e 3. Implemente los cambios necesarios para que el programa admita la creacin de ms o a de un thread productor y ms de un thread consumidor. Ejecute el nuevo prograa ma lanzando varios productores y varios consumidores. Dibuje el diagrama de la ejecucin (mtodos tiempo). o e 4. Aada los cambios necesarios al applet que se ha desarrollado en prcticas anteriores n a para que tenga el mismo funcionamiento que la aplicacin Productor/Consumidor. o Adems: a El Productor generar los enteros impares sucesivos y los colocar en el campo a a de texto compartido. El Consumidor ha de recoger los valores del campo de texto y sumarlos. El Productor indica el nal de su tarea colocando el valor -1 en el campo de texto, mientras que el Consumidor utiliza el -1 como seal para informar de n la suma. Finalmente cuando el usuario hace click en el botn del applet se lanzan los o threads. Dibuje el diagrama de la ejecucin (mtodos tiempo). o e

Cap tulo 6

Direcciones IP y Nombres de Dominio


El objetivo de esta prctica es mostrar el modo de funcionamiento de las clase Java a para denir nombres de recursos en Internet.

6.1.

La clase InetAddress

La clase InetAddress proporciona objetos que se pueden utilizar para manipular tanto direcciones IP como nombres de dominio.

Ejemplo
El ejemplo TestInetAddress.java trata de ilustrar la utilizacin de varios de los mtoo e dos de la clase InetAddress. Para que el programa se ejecute correctamente y no aparezca una excepcin del tipo UnknownHostException, hay que estar conectados convenienteo mente. En caso de conectarse a un proveedor de Internet, la asignacin de direcciones es o automtica por parte del ISP (Internet Service Provider ), con lo cual se va a obtener una a direccin diferente en cada conexin. o o
import java.net.*; class TestInetAddress { public static void main( String[] args ) { try { System.out.println( "-> Direccion IP de una URL, por nombre" ); InetAddress address = InetAddress.getByName( "nereida.deioc.ull.es" ); System.out.println( address ); // Extrae la direccin IP a partir de la cadena que se o // encuentra a la derecha de la barra /, luego proporciona // esta direccin IP como argumento de llamada al mtodo getByName() o e System.out.println( "-> Nombre a partir de la direccion" );

26

Herramientas y Lenguajes de Programacin 06-07 o

27

int temp = address.toString().indexOf( / ); address = InetAddress.getByName( address.toString().substring(temp+1) ); System.out.println( address ); System.out.println( "-> Direccion IP actual de LocalHost" ); address = InetAddress.getLocalHost(); System.out.println( address ); System.out.println( "-> Nombre de LocalHost a partir de la direccion" ); temp = address.toString().indexOf( / ); address = InetAddress.getByName( address.toString().substring(temp+1) ); System.out.println( address ); System.out.println( "-> Nombre actual de LocalHost" ); System.out.println( address.getHostName() ); System.out.println( "-> Direccion IP actual de LocalHost" ); // Coge la direccin IP como un array de bytes o byte[] bytes = address.getAddress(); // Convierte los bytes de la direccin IP a valores sin o // signo y los presenta separados por espacios for( int cnt=0; cnt < bytes.length; cnt++ ) { int uByte = bytes[cnt] < 0 ? bytes[cnt]+256 : bytes[cnt]; System.out.print( uByte+" " ); } System.out.println(); } catch( UnknownHostException e ) { System.out.println( e ); System.out.println( "Debes estar conectado para que esto funcione bien." ); } } }

6.2.

Ejercicios

1. Compile y ejecute el ejemplo TestInetAddress. 2. Existe un gran nmero de nombres de dominio y direcciones IP en Internet, por lo u que es deseable un servicio que permita asociar un nombre con la direccin correso pondiente. Dicho servicio se conoce con el nombre de DNS (Servicio de Nombres de Dominio - Domain Name Service). Un ejemplo de este servicio es la utilidad UNIX nslookup. Utilizando nslookup, se puede encontrar el nombre de dominio de una direccin IP o viceversa, la direccin IP de un nombre de dominio. Haciendo uso o o de la clase InetAddress escriba un programa Java Nslookup.java que muestre la direccin IP de una mquina dado su nombre. o a Usage: java Nslookup <hostname>

Herramientas y Lenguajes de Programacin 06-07 o

28

3. Escriba un programa Java IPtoname.java que dada la direccin IP de una mquina o a muestre su nombre. Usage: java IPtoname <IP address> 4. Cul es la IP de la direccin de red asignada a la Universidad de La Laguna?. a o Qu clase de red es (A hasta E)? e 5. Cul es el nombre de dominio del servidor web de la Universidad de La Laguna?. a Cul es su direccin IP? a o 6. Utilice los programas que ha implementado para completar la siguiente tabla: Direccin IP o 127.0.0.1 193.145.98.254 224.0.1.24 www.mit.edu Nombre de Dominio

cepba.upc.es

Cap tulo 7

Las clases Java DatagramPacket y DatagramSocket


El objetivo de esta sesin prctica es mostrar el modo de funcionamiento de las clases o a Java para denir datagramas y sockets de datagrama.

7.1.

Introduccin o

Las redes actuales utilizan el packet switching para la transferencia de datos. Los datos se envuelven en paquetes que se transeren desde un origen a un destino, donde se extraen de uno en uno los datos de uno o ms paquetes para reconstruir el mensaje original. a Los nodos que se comunican a travs de Internet utilizan principalmente dos protocolos: e tcp - Transsmision Control Protocol udp - (Universal | User) Datagram Protocol El protocolo udp - (User | Universal) Datagram Protocol - se utiliza para comunicaciones en la que no se garantiza una transmisin able (reliable). udp no est orientado a o a conexin, por lo tanto no garantiza la entrega. udp env paquetes de datos independientes, o a denominados datagramas, desde una aplicacin a otra. o El env de datagramas es similar a enviar una carta a travs del servicio postal: El o e orden de salida no es importante y no est garantizado, y cada mensaje es independiente a de cualquier otro. En las comunicaciones basadas en datagramas como las udp, el paquete de datagramas contiene el nmero de puerto de su destino y udp encamina el paquete a la aplicacin u o apropiada, como ilustra la gura 8.3. El API Java para udp proporciona una abstracin del paso de mensajes, esto es, o la forma ms simple de comunicacin entre ordenadores. Esto hace posible a un proceso a o emisor transmitir un unico mensaje a un proceso receptor. Los paquetes independientes que contienen esos mensajes se denominan datagramas. En Java, el emisor especica el

29

Herramientas y Lenguajes de Programacin 06-07 o

30

Figura 7.1:

destino usando un socket (una referencia indirecta a un puerto particular usada por el proceso receptor en la mquina receptora). a Un datagrama enviado mediante udp es trasmitido desde un proceso emisor a un proceso receptor sin reconocimiento o recomprobaciones. Si tiene lugar un fallo, el mensaje puede no llegar. Un datagrama es transmitido entre procesos cuando un proceso lo env a y otro proceso lo recibe. Cualquier proceso que necesite enviar o recibir mensajes debe en primer lugar crear un socket a un direccin de Internet y a un puerto local. Un servidor o enlazar ese socket a un puerto servidor - uno que se hace conocido a los clientes de manera a que puedan enviar mensajes al mismo. Un cliente enlaza su socket a cualquier puerto local libre. El mtodo receptor devuelve la direccin de Internet y el puerto del emisor, adems e o a del mensaje, permitiendo a los receptores enviar una respuesta. Las clases Java para establecer comunicaciones mediante datagramas son: DatagramPacket y DatagramSocket.

7.2.

La clase DatagramPacket

La clase DatagramPacket proporciona un constructor que permite crear instancias de un array de bytes parar: el mensaje, la longitud del mensaje, la direccin Internet y el o puerto local del socket de destino, de la siguiente forma:
array de bytes que contiene el mensaje longitud del mensaje direccin Intenet o n mero de puerto u

Los objetos del tipo DatagramPacket se pueden transmitir entre procesos cuando un proceso los env y otro los recibe. a Esta clase proporciona otro constructor para usarlo cuando se recibe un mensaje. Sus argumentos especican un array de bytes en el que recibir el mensaje y la longitud del array. Cuando se recibe un mensaje se pone en el DatagramPacket junto con su longitud, la direccin de Internet y el puerto del socket de env o o. Se puede obtener el mensaje del objeto DatagramPacket mediante el mtodo getData(). e Los mtodos getPort() y getAddress() permiten obtener el puerto y la direccin Internet e o del objeto de tipo DatagramPacket.

Herramientas y Lenguajes de Programacin 06-07 o

31

El proceso receptor del mensaje tiene que especicar un array de bytes de un tamao n determinado en el cual recibir el mensaje, esto es, ha de predecir el Tamao del Mensaje. Si n el mensaje es muy grande para el array se trunca cuando llega. El protocolo ip subyacente permite longitudes de paquetes de ms de 216 bytes, que incluye tanto las cabeceras como a los mensajes. Sin embargo, la mayor de los entornos imponen una restriccin en el tamao a o n a 8 kilobytes. Cualquier aplicacin que necesite mensajes mayores que el mximo, debe o a fragmentarlos en pedazos de ese tamao. Generalmente, una aplicacin decidir sobre un n o a tamao que no sea excesivamente grande pero que se adecue a su uso previsto. n

7.3.

La clase DatagramSocket

La clase DatagramSocket da soporte a sockets para el env y recepcin de datagramas o o udp. Se proporciona un constructor que toma un puerto como argumento, para que sea usado por los procesos que necesitan usar un puerto particular. Tambin se proporciona e un constructor sin argumentos que permite al sistema escoger un puerto local libre. Estos constructores pueden lanzar una excepcin del tipo SocketException si el puerto ya o est en uso o si est reservado. a a Esta clase cuenta con los siguientes mtodos: e send() y receive(). Estos mtodos permiten transmitir datagramas entre un par de sockets. El argue mento del send es una instancia de un DatagramPacket que contiene un mensaje y su destino. El argumento del receive es un objeto DatagramPacket vac en el o cual se pondr el mensaje, su longitud y su origen. Tanto el mtodo send() como el a e receive() pueden lanzar una IOException. Las comunicaciones mediante datagramas de udp usan env no bloqueantes (nonos blocking sends) y recepciones bloqueantes (blocking receives). Las operaciones de env retornan cuando estas han dado el mensaje a los protocolos ip o udp subo yacentes, los cuales son responsables de trasmitirlos a su destino. En la llegada, el mensaje es puesto en una cola por el socket que est asociado al puerto de destino. a El mensaje puede ser recogido de la cola por una excepcin o llamadas futuras de o recepcion (receive()) sobre ese socket. Los mensajes son descartados en el destino si ningn proceso tiene asociado un socket al puerto de destino. El mtodo u e receptor (receive()) se bloquea hasta que se recibe un datagrama, a menos que se establezca un tiempo l mite (timeout) sobre el socket. Si el proceso que invoca al mtodo receive() tiene otra tarea que hacer mientras espera por el mensaje, e deber planicarse en un ujo de ejecucin (thread ) separado. a o setSoTimeout(). Este mtodo permite establecer un tiempo de espera. Con un tiempo de espera e establecido, el mtodo receive() se bloquear por el tiempo especicado y entonces e a lanzar una InterruptedIOException(). a

Herramientas y Lenguajes de Programacin 06-07 o connect().

32

Este mtodo se utiliza para conectar a un puerto remoto particular y una direccin e o de Internet, en este caso el socket slo es capaz de enviar y recibir mensajes desde o esa direccin. o

7.4.

Ejercicios

El siguiente cdigo utiliza sockets datagrama para intercambiar una unica cadena de o datos. La lgica del programa es lo ms sencilla posible para subrayar la sintxis bsica o a a a de las comunicaciones entre procesos. El emisor crea un paquete datagrama que contiene una direccin de destino, mientras que el paquete datagrama del receptor no incluye una o direccin de destino. o

import java.net.*; import java.io.*; public class Example1Sender { public static void main(String[] args) { if (args.length != 3) System.out.println ("This program requires three command line arguments"); else { try { InetAddress receiverHost = InetAddress.getByName(args[0]); int receiverPort = Integer.parseInt(args[1]); String message = args[2]; // instantiates a datagram socket for sending the data DatagramSocket mySocket = new DatagramSocket(); byte[ ] buffer = message.getBytes( ); DatagramPacket datagram = new DatagramPacket(buffer, buffer.length, receiverHost, receiverPort); mySocket.send(datagram); mySocket.close( ); } // end try catch (Exception ex) { ex.printStackTrace( ); } } // end else } // end main } // end class

El socket el emisor se enlaza a un nmero de puerto no especicado, mientras que el u socket del receptor se enlaza a un nmero de puerto espec u co, para que el emisor pueda escribir este nmero de puerto en su datagrama como destino. u

Herramientas y Lenguajes de Programacin 06-07 o

33

import java.net.*; import java.io.*; public class Example1Receiver { public static void main(String[] args) { if (args.length != 1) System.out.println("This program requires a command line argument."); else { int port = Integer.parseInt(args[0]); final int MAX_LEN = 10; // This is the assumed maximum byte length of the datagram to be received. try { DatagramSocket mySocket = new DatagramSocket(port); // instantiates a datagram socket for receiving the data byte[ ] buffer = new byte[MAX_LEN]; DatagramPacket datagram = new DatagramPacket(buffer, MAX_LEN); mySocket.receive(datagram); String message = new String(buffer); System.out.println(message); mySocket.close( ); } // end try catch (Exception ex) { ex.printStackTrace( ); } } // end else } // end main } // end class

1. Compile y ejecute el cdigo del ejemplo en una mquina usando localhost como o a nombre de mquina. Por ejemplo se puede introducir el comando: a java Example1Sender localhost 12345 Hola Ejecute los dos programas arrancando primero al receptor y despus al emisor. El e mensaje que se env no deber exceder la longitud mxima permitida que es de 10 e a a caracteres. Describa el resultado de la ejecucin. o 2. Repita el ejercicio anterior utilizando las mquinas manis.etsii.ull.es y timple.a etsii.ull.es. 3. Vuelva a ejecutar las aplicaciones del apartado 1, esta vez ejecutando primero al emisor y luego al receptor. Describa y explique el resultado. 4. Repita el apartado 1, esta vez mandando un mensaje de longitud ms grande que la a mxima longitud permitida. a Describa y explique la salida producida.

Herramientas y Lenguajes de Programacin 06-07 o

34

5. Aada cdigo al proceso receptor de manera que el plazo mximo de bloqueo del n o a receive sea de cinco segundos. Lance el proceso receptor pero no el proceso emisor. Cul es el resultado? Descr a balo y expl quelo. 6. Modique el cdigo original de manera que el receptor ejecute indenidamente un o bucle que reciba y muestre los datos recibidos. Comp lelo y ejectelo de la siguiente u forma: lance al receptor ejecute el emisor enviando un mensaje mensaje 1 en otra ventana, lanzar otra instancia del emisor, mandando un mensaje mensaje 2. Describa y explique el resultado. 7. Modique el cdigo original de manera que el emisor utilice el mismo socket para o enviar el mismo mensaje a dos receptores diferentes. Primero lance los dos receptores y despus al emisor. Cada receptor recibe el mensaje? Describa y explique el e resultado. 8. Modique el cdigo original de manera que el emisor utilice dos socket distintos o para enviar el mismo mensaje a dos receptores diferentes. Primero lance los dos receptores y despus al emisor. Cada receptor recibe el mensaje? Describa y explique e el resultado. 9. Modique el cdigo del ultimo paso de modo que el emisor env de forma permao e nente, suspendindose durante 3 segundos entre cada env e o. Modique el receptor de manera que ejecute un bucle que repetidamente reciba datos y luego los muestre. Compile y ejecute los programas durante unos cuentos segundos antes de teminarlos con Ctrl-C. Describa y explique el resultado. 10. Modique el cdigo original de modo que el emisor tambin reciba un mensaje del o e receptor. Utilizar slo un socket en cada proceso. Entregue este cdigo. o o

Cap tulo 8

Las clases Java Socket y ServerSocket


El objetivo de esta sesin prctica es mostrar el modo de funcionamiento de las clases o a Java para denir sockets de ujo (stream).

8.1.

Introduccin o

El paradigma Cliente/Servidor es quizs el ms conocido de los paradigmas para aplia a caciones de red. Se usa para describir un modelo de interaccin entre dos procesos, que o se ejecutan de forma simultnea. Este modelo es una comunicacin basada en una serie a o de preguntas y respuestas, que asegura que si dos aplicaciones intentan comunicarse, una comienza la ejecucin y espera indenidamente que la otra le responda y luego continua o con el proceso.

Figura 8.1: Paradigma Cliente/Servidor

35

Herramientas y Lenguajes de Programacin 06-07 o Los dos componentes del paradigma son: Cliente: aplicacin que inicia la comunicacin, es dirigida por el usuario. o o Servidor: es quien responde a los requerimientos de los clientes, son procesos que se estn ejecutando indenidamente. a

36

Los procesos clientes son ms sencillos que los procesos de los servidores, los primeros a no requieren de privilegios de sistemas para funcionar, en cambio los procesos servidores s . Los usuarios cuando quieren acceder a un servicio de red, ejecutan un software cliente. El diseo de los servidores debe ser muy cuidadoso, debe incluir cdigo para la manipulan o cin de: o autenticacin: vericar la identidad del cliente. o seguridad de datos: para que estos no puedan ser accedidos inapropiadamente. privacidad : garantizar que la informacin privada de un usuario, no sea accedida por o alguien no autorizado. proteccin: asegurar que las aplicaciones no monopolicen los recursos del sistema. o autorizacin: vericar si el cliente tiene acceso al servicio proporcionado por el sero vidor. La mayor de las comunicaciones punto-a-punto en las redes (incluida Internet), estn a a basadas en el modelo Cliente/Servidor. Desde el punto de vista Internet/Intranet, se tendr a: Un servidor es un ordenador remoto en algn lugar de la red que proporciona u informacin segn peticin. o u o Un cliente funciona en su ordenador local, se comunica con el servidor remoto, y pide a ste informacin. e o El servidor env la informacin solicitada. a o Un unico servidor t picamente sirve a una multitud de clientes, ahorrando a cada uno de ellos el problema de tener la informacin instalada y almacenada localmente. o

8.2.

Sockets

Normalmente, un servidor se ejecuta en una mquina espec a ca y tiene un socket asociado a un nmero de puerto espec u co. El servidor simplemente espera a la escucha en el socket a que un cliente se conecte con una peticin. El cliente conoce el nombre de la o

Herramientas y Lenguajes de Programacin 06-07 o

37

Figura 8.2: socket Servidor

mquina sobre la que est ejecutndose el servidor y el nmero de puerto al que est coneca a a u a tado. Solicitar una conexin consiste en intentar establecer una cita con el servidor en el o puerto de la mquina servidora. a Si todo va bien, el servidor acepta la conexin. Pero antes, el servidor crea un nuevo o socket en un puerto diferente. Es necesario crear un nuevo socket (y consecuentemente un nmero de puerto diferente) de forma que en el socket original se continue a la escucha de u las peticiones de nuevos clientes mientras se atiende a las necesidades del cliente conectado. En el cliente, si se acepta la conexin, el socket se crea satisfactoriamente y se puede utilizar o para comunicarse con el servidor.

Figura 8.3: socket Cliente Un socket es el extremo nal de un enlace punto-a-punto que comunica a dos programas ejecutndose en una red. a Los sockets siempre estn asociados a un nmero de puerto que es utilizado por tcp a u para identicar la aplicacin a la que est destinada la solicitud y poder redirigirsela. o a

8.2.1.

La clase Socket

La clase Socket del paquete java.net es fcil de usar comparada con la que propora cinan otros lenguajes. Java oculta las complejidades derivadas del establecimiento de la conexin de red y del env de datos a travs de ella. En esencia, el paquete java.net o o e proporciona la misma interfaz de programacin que se utiliza cuando se trabaja con aro chivos. Ejemplo 1 El siguiente ejemplo, ClienteFecha.java, muestra la implementacin de un cliente que o accede al servicio UNIX fecha y hora. El servidor concreto al que se conecta es al localhost. El servicio fecha y hora, por convenio, siempre est en el puerto 13. Lo a

Herramientas y Lenguajes de Programacin 06-07 o

38

que ocurre es que el software del servidor est ejecutndose continuamente en la mquina a a a remota, esperando cualquier trco de red que hable con l .en el puerto 13. Cuando el a e Sistema Operativo de este servidor recupera un paquete de red que contiene una peticin o para conectar con el puerto 13, activa el servicio de escucha del servidor y establece la conexin, que permanece activa hasta que es nalizada por alguna de las dos partes. o
import java.net.*; import java.io.*; import java.util.*; class ClienteFecha { public static void main( String[] args ) { String servidor = "localhost"; int puerto = 13; // puerto de daytime try { // Se abre un socket conectado al servidor y al // puerto estndar de echo a Socket socket = new Socket( servidor,puerto ); System.out.println( "Socket Abierto." ); // Se consigue el canal de entrada BufferedReader entrada = new BufferedReader( new InputStreamReader( socket.getInputStream() ) ); System.out.println( System.out.println( System.out.println( System.out.println( "Hora actual en localhost:" ); "\t"+entrada.readLine() ); "Hora actual con la clase date:" ); "\t" + new Date() );

// Se cierra el canal de entrada entrada.close(); // Se cierra el socket socket.close(); } catch( UnknownHostException e ) { System.out.println( e ); System.out.println( "Debes estar conectado para que esto funcione bien." ); } catch( IOException e ) { System.out.println( e ); } } }

Ejemplo 2 El ejemplo EchoClient.java muestra la implementacin de un cliente que accede al o servicio UNIX eco. El servidor concreto al que se conecta es a manis en la Escuela. El servicio eco, por convenio, siempre est en el puerto 7. Aunque con frecuencia por a razones de seguridad est cerrado. a

Herramientas y Lenguajes de Programacin 06-07 o

39

import java.io.*; import java.net.*; public class EchoClient { public static void main(String[] args) throws IOException { String serverName = "exthost.csi.ull.es"; int portNumber = 7; Socket echoSocket = null; PrintWriter out = null; BufferedReader in = null; try { echoSocket = new Socket(serverName, portNumber); out = new PrintWriter(echoSocket.getOutputStream(), true); in = new BufferedReader(new InputStreamReader( echoSocket.getInputStream())); } catch (UnknownHostException e) { System.err.println("Dont know about host: " + serverName); System.exit(1); } catch (IOException e) { System.err.println("Couldnt get I/O for " + "the connection to: " + serverName); System.exit(1); } BufferedReader stdIn = new BufferedReader( new InputStreamReader(System.in)); String userInput; while ((userInput = stdIn.readLine()) != null) { out.println(userInput); System.out.println("echo: " + in.readLine()); } out.close(); in.close(); stdIn.close(); echoSocket.close(); } }

8.2.2.

La clase ServerSocket

La clase ServerSocket es la que se utiliza a la hora de crear servidores, al igual que como se ha visto, la clase Socket se utilizaba para crear clientes. Ejemplo Este ejemplo muestra cmo escribir un servidor y su cliente. Est sacado del Tutorial o a de Java de Sun. El servidor sirve chistes. Funciona de la siguiente forma:

Herramientas y Lenguajes de Programacin 06-07 o miranda:~/clases/psd/> java KnockKnockClient Server: Knock! Knock! Whos there? Client: Whos there? Server: Turnip Turnip who? Client: Turnip who? Server: Turnip the heat, its cold in here! Want another? (y/n) n Client: n Server: Bye. miranda:~/clases/psd/>

40

El ejemplo consta de dos programas Java ejecutndose de forma independiente KnockKnockClient a y KnockKnockServer. Sin embargo, est constituido por tres cheros: a KnockKnockServer.java (implementacin del Servidor) o KnockKnockProtocol.java (implementacin del protocolo) o KnockKnockClient.java (implementacin del cliente) o

8.3.

La clase Thread y la implementacin de servidores o

Existe un problema con el ejemplo del servidor de chistes de la seccin anterior. Suo ponga que queremos permitir que varios usuarios se conecten a la vez. Lo normal es que un servidor est ejecutndose constantemente en un ordenador, y que los usuarios se conecten e a simultneamente al mismo. En el ejemplo que hemos visto, slo se admite la conexin de a o o un usuario. Esto podemos arreglarlo usando threads. Cada vez que sepamos que el programa ha establecido una nueva conexin, esto es, o siempre que una peticin de servicio tenga xito, lanzaremos un nuevo thread que ser el o e a encargado de monitorizar la coneccin entre el servidor y ese cliente. El programa principal o slo se encargar de seguir esperando nuevas conexiones. Para implementar esto, el bucle o a principal del servidor deber ser algo como: a
while (true) { Socket incoming = s.accept(); Thread t = new ThreadServerHandler(incoming); t.start(); }

La clase ThreadServerHandler extiende a la clase Thread y contiene el bucle de comunicacin entre el servidor y el cliente en su mtodo run(). o e

Herramientas y Lenguajes de Programacin 06-07 o

41

class ThreadServerHandler extends Thread { ... public void run() { try { // Establecer los flujos de entrada/salida para el socket // Procesar las entradas y salidas segn el protocolo u // cerrar el socket } catch (Excepction e) { // manipular las excepciones } } }

Ejemplo Este ejemplo ampl al de la seccin anterior mostrando cmo escribir un servidor que a o o atiende a mltiples clientes. El modo de funcionamiento es exactamente el mismo. u El ejemplo consta de dos programas Java ejecutndose de forma independiente Knocka KnockClient y KKMultiServer. Para probarlo en una terminal lance al servidor, y en dos o ms nuevas terminales lance a varios clientes. La aplicacin est constituida por los a o a siguientes cheros: KnockKnockProtocol.java (implementacin del protocolo, no cambia respecto al o ejemplo anterior) KnockKnockClient.java (implementacin del cliente, no cambia respecto al ejemplo o anterior) KKMultiServerThread.java (implementacin de un thread Servidor) o KKMultiServer.java (implementacin del Servidor) o

8.4.

Ejercicios

1. Modicar el ejemplo Cliente de Eco del enunciado de manera que: Se especique en la l nea de comandos el nombre de la mquina servidora y el a nmero de puerto. Si no se especica nada, el servidor por defecto ser localu a host y el puerto el nmero 7. u Para indicar el nal de una sesin cliente el usuario ha de introducir por teclado o un punto .. Cuando se introduzca un punto se ha de salir del bucle de entrada y se ha de cerrar el socket de datos. Solucin: o EchoClient.java

Herramientas y Lenguajes de Programacin 06-07 o

42

2. Implementar un servidor de eco como el que proporcionan los servidores Unix en el puerto 7. Disee un servidor iterativo, para ello: n Se ha de especicar en la l nea de comandos el nmero de puerto en el que u el servidor acepta conexiones (por ejemplo, 8180). Si no se especica nada, el nmero de puerto por defecto ser el 7. u a El servidor se ha de quedar esperando las solicitudes de conexin de los clientes. o Utilizando la clase BufferedReader junto con la clase InputStreamReader se ha de abrir un ujo de entrada desde el socket servidor. Con la clase PrintWriter junto con la clase OutputStreamWriter abrir un ujo de salida al socket. El programa ha de actuar como repetidor, recogiendo las l neas que llegan por el canal de entrada y escribindolas en el canal de salida, hasta que el usuario le e indique que ha terminado, escribiendo un punto .. Cuando ya no haya ms a l neas que leer, se recibir un punto, lo cual har que el servidor salga del bucle a a de entrada y cierre el socket servidor. Para probar que funciona, ejecute el programa servidor en un consola, y en otra terminal escriba: telnet 127.0.0.1 8180. Solucin: o EchoServer.java MyStreamSocket.java 3. Con los dos programas anteriores realice las siguientes operaciones: Ejecute los programas empezando por el servidor y a continuacin el cliente. o En una terminal diferente arranque a otro cliente. Dibuje el diagrama de secuencia. Se pueden realizar las dos sesiones en paralelo? Explique su respuesta. 4. Modicar el servidor de eco del ejercicio 2, para que sea un servidor concurrente. Solucin: o EchoServer.java 5. Con el programa anterior y el cliente de eco del ejercicio 1 realice las siguientes operaciones: Ejecute los programas empezando por el servidor y a continuacin el cliente. o En una terminal diferente arranque a otro cliente. Dibuje el diagrama de secuencia. Se pueden realizar las dos sesiones del cliente en paralelo? Explique su respuesta. 6. Describa las diferencias, desde el punto de vista del cliente, entre un servidor iterativo y un servidor concurrente para un servicio que involucre mltiples rondas de u intercambios de mensajes.

Herramientas y Lenguajes de Programacin 06-07 o

43

8.5.

Cdigos Fuente del Servidor de chistes iterativo o

import java.net.*; import java.io.*; public class KnockKnockProtocol { private static final int WAITING = 0; private static final int SENTKNOCKKNOCK = 1; private static final int SENTCLUE = 2; private static final int ANOTHER = 3; private static final int NUMJOKES = 5; private int state = WAITING; private int currentJoke = 0; private String[] clues = { "Turnip", "Little Old Lady", "Atch", "Who", "Who" }; private String[] answers = { "Turnip the heat, its cold in here!", "I didnt know you could yodel!", "Bless you!", "Is there an owl in here?", "Is there an echo in here?" }; public String processInput(String theInput) { String theOutput = null; if (state == WAITING) { theOutput = "Knock! Knock!"; state = SENTKNOCKKNOCK; } else if (state == SENTKNOCKKNOCK) { if (theInput.equalsIgnoreCase("Whos there?")) { theOutput = clues[currentJoke]; state = SENTCLUE; } else { theOutput = "Youre supposed to say \"Whos there?\"! " + "Try again. Knock! Knock!"; } } else if (state == SENTCLUE) { if (theInput.equalsIgnoreCase(clues[currentJoke] + " who?")) { theOutput = answers[currentJoke] + " Want another? (y/n)"; state = ANOTHER; } else { theOutput = "Youre supposed to say \"" + clues[currentJoke] + " who?\"" + "! Try again. Knock! Knock!"; state = SENTKNOCKKNOCK; } } else if (state == ANOTHER) { if (theInput.equalsIgnoreCase("y")) { theOutput = "Knock! Knock!"; if (currentJoke == (NUMJOKES - 1)) currentJoke = 0;

Herramientas y Lenguajes de Programacin 06-07 o

44

else currentJoke++; state = SENTKNOCKKNOCK; } else { theOutput = "Bye."; state = WAITING; } } return theOutput; } } import java.io.*; import java.net.*; public class KnockKnockClient { public static void main(String[] args) throws IOException { Socket kkSocket = null; PrintWriter out = null; BufferedReader in = null; try { kkSocket = new Socket("localhost", 4444); out = new PrintWriter(kkSocket.getOutputStream(), true); in = new BufferedReader(new InputStreamReader(kkSocket.getInputStream())); } catch (UnknownHostException e) { System.err.println("Dont know about host: manis.csi.ull.es."); System.exit(1); } catch (IOException e) { System.err.println("Couldnt get I/O for the connection to: manis.csi.ull.es."); System.exit(1); } BufferedReader stdIn = new BufferedReader(new InputStreamReader(System.in)); String fromServer; String fromUser; while ((fromServer = in.readLine()) != null) { System.out.println("Server: " + fromServer); if (fromServer.equals("Bye.")) break; fromUser = stdIn.readLine(); if (fromUser != null) { System.out.println("Client: " + fromUser); out.println(fromUser); } } out.close(); in.close(); stdIn.close(); kkSocket.close(); } }

Herramientas y Lenguajes de Programacin 06-07 o

45

import java.net.*; import java.io.*; public class KnockKnockServer { public static void main(String[] args) throws IOException { ServerSocket serverSocket = null; try { serverSocket = new ServerSocket(4444); System.out.println("estoy despus de crear el socket"); e } catch (IOException e) { System.err.println("Could not listen on port: 4444."); System.exit(1); } Socket clientSocket = null; try { clientSocket = serverSocket.accept(); System.out.println("estoy despus de aceptar un cliente"); e } catch (IOException e) { System.err.println("Accept failed."); System.exit(1); } PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true); BufferedReader in = new BufferedReader( new InputStreamReader( clientSocket.getInputStream())); String inputLine, outputLine; KnockKnockProtocol kkp = new KnockKnockProtocol(); outputLine = kkp.processInput(null); out.println(outputLine); while ((inputLine = in.readLine()) != null) { outputLine = kkp.processInput(inputLine); out.println(outputLine); if (outputLine.equals("Bye.")) break; } out.close(); in.close(); clientSocket.close(); serverSocket.close(); } }

Herramientas y Lenguajes de Programacin 06-07 o

46

8.6.

Cdigos Fuente del Servidor de chistes concurrente o

import java.net.*; import java.io.*; public class KKMultiServer { public static void main(String[] args) throws IOException { ServerSocket serverSocket = null; boolean listening = true; try { serverSocket = new ServerSocket(4444); } catch (IOException e) { System.err.println("Could not listen on port: 4444."); System.exit(-1); } while (listening) new KKMultiServerThread(serverSocket.accept()).start(); serverSocket.close(); } }

import java.net.*; import java.io.*; public class KKMultiServerThread extends Thread { private Socket socket = null; public KKMultiServerThread(Socket socket) { super("KKMultiServerThread"); this.socket = socket; } public void run() { try { PrintWriter out = new PrintWriter(socket.getOutputStream(), true); BufferedReader in = new BufferedReader( new InputStreamReader( socket.getInputStream())); String inputLine, outputLine; KnockKnockProtocol kkp = new KnockKnockProtocol(); outputLine = kkp.processInput(null); out.println(outputLine); while ((inputLine = in.readLine()) != null) { outputLine = kkp.processInput(inputLine); out.println(outputLine); if (outputLine.equals("Bye")) break; }

Herramientas y Lenguajes de Programacin 06-07 o

47

out.close(); in.close(); socket.close(); } catch (IOException e) { e.printStackTrace(); } } }

S-ar putea să vă placă și