• No se han encontrado resultados

PARA LAS DIRECCIONES DE INTERNET

In document Libro Final Sistemas Distribuidos PDF (página 99-111)

COMUNICACIÓN A BAJO NIVEL, SOCKETS

PARA LAS DIRECCIONES DE INTERNET

Como los paquetes IP que subyacen a TCP y UDP se envían en direcciones internet, java proporciona una clase InetAddres, para representar las direcciones internet. Los usuarios de esta clase se refieren a los computadores por sus nombres de host en el servicio de nombres de dominio.

2.1. Comunicación de datagramas UDP

Un datagrama enviado por UDP se transmite desde un proceso emisor a un proceso receptor sin acuse de recibo ni reintentos. Si algo falla, el mensaje puede no llegar a su destino. Se

Figura 3. Proceso de transmision de datos con Streams

Figura 3. Proceso de transmision de datos con datagramas.

transmite un datagrama entre proceso cuando uno lo envía y el otro lo recibe, cualquier proceso que necesite enviar o recibir mensajes debe crear primero un conector asociado a una dirección de internet y a un puerto local. Un servidor enlazara su conector a un puerto de de servidor (uno que resulte conocido a los clientes de forma que puedan enviarle mensajes). Un cliente ligara su conector a cualquier puerto local libre. El método recibe devolverá, además del mensaje, la dirección de internet y el puerto del emisor, permitiendo al receptor enviar la correspondiente respuesta.

API java para datagramas UDP.

La API java proporciona una comunicación de datagramas por medio de dos clases: Datagrama Packet y DatagramaSocket.

Datagrama Packet:

Esta clase proporciona un constructor que crea una instancia compuesta por una cadena de bytes que almacena el mensaje, la longitud del mensaje y la dirección internet y el número de puerto local del conector destino.

Cadena de bytes conteniendo el mensaje Longitud del mensaje. Dirección de internet Numero de puerto

Las instancias de DatagramaPacket podrán ser transmitidas entre procesos cuando uno la envía y el otro la recibe.

DatagramaSocket:

Esta clase maneja conectores para enviar y recibir datagramas UDP. Proporciona un constructor que toma un numero de puerto como argumento, apropiado para los procesos que necesitan utilizar un puerto concreto. También proporciona un constructor sin argumentos que permite que el sistema elija un puerto de entre los libres. Estos constructores pueden lanzar una excepción SocketException si el puerto ya esta siendo usado o si se especifica un puerto reservado.

Figura 3. Paquete del datagrama

Código java de un cliente UDP enviando un mensaje a un servidor y recogiendo su respuesta: El código muestra un programa de un cliente que crea un conector, envía un mensaje a un servidor en el puerto 6789, y después espera una respuesta. Los argumentos para el método main proporcionan un mensaje y el nombre del DNS de host del servidor. El mensaje se convierte en una cadena de bytes y el nombre DNS del host a la correspondiente dirección de internet.

import java.net.*; import java.io.*;

public class UDPClient{

public static void main(String args[]){

// args give message contents and server hostname DatagramSocket aSocket = null;

try {

aSocket = new DatagramSocket(); byte [] m = args[0].getBytes();

InetAddress aHost = InetAddress.getByName(args[1]);

int serverPort = 6789;

DatagramPacket request = new DatagramPacket(m, args[0].length(), aHost, serverPort);

aSocket.send(request);

byte[] buffer = new byte[1000]; DatagramPacket reply = new DatagramPacket(buffer, buffer.length); aSocket.receive(reply); System.out.println("Reply: " + new String(reply.getData())); }catch (SocketException e) {System.out.println("Socket: " + e.getMessage());

}catch (IOException e){System.out.println("IO: " +

e.getMessage());}

}finally {if(aSocket != null) aSocket.close();} }

}

 Código java de un servidor UDP recibiendo peticiones

y las devuelve al cliente en forma repetitiva.

El código muestra el programa para el correspondiente servidor el cual crea un conector ligado a su puerto de servidor 6789 y entonces espera repetidamente a los mensajes de petición de los clientes, a los cuales responde mandando de vuelta el mismo mensaje.

import java.net.*; import java.io.*;

public class UDPServer{

public static void main(String args[]){ DatagramSocket aSocket = null;

try{

aSocket = new DatagramSocket(6789); byte[] buffer = new byte[1000];

while(true){

DatagramPacket request = new

DatagramPacket(buffer, buffer.length); aSocket.receive(request); DatagramPacket reply = new DatagramPacket(request.getData(),

request.getLength(), request.getAddress(), request.getPort());

aSocket.send(reply); }

}catch (SocketException e)

{System.out.println("Socket: " + e.getMessage()); }catch (IOException e)

{System.out.println("IO: " + e.getMessage());} }finally {if(aSocket != null) aSocket.close();} }

}

2.2. Comunicación de Streams TCP

La API para el prtocolo TCP, proporciona la abstracción de un flujo de bytes (stream) en el que pueden escribirse y leerse datos.

La API para la construcción por streams supone que en el momento de establecer una conexión uno de ellos juega el papel de cliente y el otro juega de servidor, aunque después se comuniquen de igual a igual. El rol del cliente implica la creación de un conector, de tipo stream, sobre cualquier puerto y la posterior petición de conexión con el servidor en su puerto de servicio. El papel del servidor involucra la creación de un conector de escucha ligado al puerto de servicio y la espera de clientes que soliciten conexiones. El conector para escuchar mantiene una cola de peticiones de conexión. En el modelo de Sockets, cuando un servidor acepta una conexión, crea una nuevo conector para mantener la comunicación con el cliente, mientras que se reserva el conector del puerto de servicio para escuchar las peticiones de conexión de otros clientes.

El par de conestores el del cliente y el del servidor, se conectan por un par de streams, uno en cada dirección. Asi cada conector tiene su propio stream de entrada y de salida. Uno de los procesos del par puede enviar información al otro escribiendo en un stream de salida, y el otro puede obtener la información leyendo de su stream de entrada.

Cuando una aplicación cierra un conector, indica que no va escribir nada mas en su stream de salida, cualquier dato que se encuentre en su buffer de salida será enviado al otro extremo del stream y puesto en la cola del conector destino con una indicación de que el stream ha sido roto. El proceso en el destino puede leer los datos en la cola, pero cualquier lectura después de que la cola este vacía resultara una indicación del final del stream. Cuando un proceso finaliza su ejecución o falla, todos sus conectores se cierran y cualquier proceso que intente con él descubrirá que la conexión se ha roto.

Utilización del TCP

Muchos de los servicios utilizados se ejecutan sobre conexiones TCP, con números de puerto reservados. Entre ellos se encuentran los siguientes.

HTTP: El protocolo de transferencia de Hipertexto se utiliza en la comunicación entre un navegador y un servidor web.

FTP: El protocolo de transferencia de archivos permite leer los directorios de un computador remoto y transferir los archivos entre los computadores de una conexión.

Telnet: la herramienta Telnet proporciona acceso a un terminal en un computador remoto.

SMTP: el protocolo simple de transferencia de de correo se utiliza para enviar correos electrónicos entre computadores. API Java para los Streams TCP

La interfaz java para los Streams TCP está constituido por clases ServerSockets y Socket.

ServerSocket: esta clase está diseñada para ser utilizada por un servidor para crear un conector en el puerto de servidor que escucha las peticiones de conexión de los clientes. Su método Accept toma una petición connect de la cola, o si la cola esta vacía, se bloquea hasta que llega una petición. El resultado de ejecutar accept es una instancia de socket, un

conector que da acceso a streams para comunicarse con el cliente.

Socket: esta clase es utilizada por el par de procesos de una conexión. El cliente utiliza un constructor para crear un conector, especificando el nombre DNS de host y el puerto del servidor. Este constructor no solo crea el conector asociado con el puerto local, sino que también se conecta con el computador remoto especificado con el puerto indicado. Puede lanzar una excepción UnknowException si el nombre de host no es correcto, o una exception IOEexception si se da un error de entrada y salida.

La clase socket proporciona los métodos getinputstream y getoutputstream para accesder a los streams asociados con un conector.

 Un cliente TCP realiza una conexión a un servidor, envía una petición y recibe una respuesta

El código muestra un programa cliente donde se le da como argumento al método main un mensaje y nombre DNS del host servidor. El cliente crea un conector ligado al nombre del host y al puerto 7896. Obtiene DataInputStream y DataOuputStream delos streams de los conectores de entrada y salida respectivamente, y entonces escribe el mensaje en su stream de salida y espera a leer la respuesta en el stream de entrada.

import java.net.*; import java.io.*;

public class TCPClient {

public static void main (String args[]) {

// arguments supply message and hostname of destination Socket s = null;

try{

int serverPort = 7896;

s = new Socket(args[1], serverPort); DataInputStream in = new

DataInputStream( s.getInputStream()); DataOutputStream out =

new DataOutputStream( s.getOutputStream()); out.writeUTF(args[0]); // UTF is a string encoding see Sn 4.3

System.out.println("Received: "+ data) ; }catch (UnknownHostException e){

System.out.println("Sock:"+e.getMessage()); }catch (EOFException e)

{System.out.println("EOF:"+e.getMessage()); }catch (IOException e)

{System.out.println("IO:"+e.getMessage());} }finally {if(s!=null) try {s.close();}catch (IOExceptione)

{System.out.println ("close:"+e.getMessage());}} }

}

 Un Servidor TCP establece una conexión para cada cliente

y les reenvía peticiones.

El código muestra un programa servidor que en realiza la siguiente acción, abre un conecctor de servidor en su puerto de servicio 7896 y escucha las peticiones de conexión, connect, cuando llega una conexión crea un nuevo hilo para comunicarse con el cliente. El nuevo hilo crea un DataInputStream y un DtaOuputStream para los flujos de esntrada y salida de su conector y entonces a leer el mensaje del cliente y lo escribe de vuelta.

import java.net.*; import java.io.*;

public class TCPServer {

public static void main (String args[]) { try{

int serverPort = 7896;

ServerSocket listenSocket = new ServerSocket(serverPort);

while(true) {

Socket clientSocket = listenSocket.accept(); Connection c = new Connection(clientSocket); }

} catch(IOException e)

{System.out.println("Listen :"+e.getMessage());} }

}

class Connection extends Thread { DataInputStream in;

DataOutputStream out; Socket clientSocket;

public Connection (Socket aClientSocket) { try { clientSocket = aClientSocket; in = new DataInputStream( clientSocket.getInputStream()); out =new DataOutputStream( clientSocket.getOutputStream()); this.start(); } catch(IOException e) {System.out.println("Connection:"+e.getMessage());}

}

public void run(){

try { // an echo server String data = in.readUTF();

out.writeUTF(data); } catch(EOFException e)

{System.out.println("EOF:"+e.getMessage()); } catch(IOException e)

{System.out.println("IO:"+e.getMessage());}

} finally{ try {clientSocket.close();}catch (IOException e) {/*close failed*/}}

} }

3 REPRESENTACION EXTERNA Y EMPAQUETADO.

La información almacenada dentro d elos programas de ejecución se representa mediante estructuras de datos (por ejemplo, por conjuntos de objetos interrelacionados) mientras que la información transportada en los mensajes consiste en secuencias de bytes. Independientemente de la forma de comunicación utilizada, las estructuras de datos deben ser apalanadas (covertidas a una secuencia de bytes) antes de su transmisión y reconstruidas en el destino. Los tipos de datos primitivos transmitidos en los mensajes pueden tener valores de diferentes tipos, y no todos los computadores almacenan valores primitivos, tales como los enteros, en el mismo orden etc.

Entonces para hacer posible que dos computadores puedan intercambiar datos se puede utilizar uno de los métodos siguientes:

• Los valores se convierten a un formato externo acordado antes de la transmisión y se revierte al formato local en la recepción, si los dos computadores son del mismo tipo y lo saben, se puede omitir la transformación al formato externo.

• Los valores se transmiten según el formato del emisor junto con una indicación del formato utilizado, y el receptor los convierte si es necesario.

Hay que hacer notar sin embargo que los bytes no son alterados durante la transmisión. Para soportar RMI o RPC. Al estándar acordado para la representación de estructuras de datos y valores primitivos se denomina represetacion externa de datos.

ACTIVIDAD

 Utilice el código de datagramas UDP (cliente-servidor), para hacer un prototipo que pruebe las condiciones en las que los datagramas son, en ocasiones desechados(concejo: el programa cliente debería ser capaz de variar el numero y el tamaño de los mensajesque envía; el servidor debería detectar cuando se ha perdido un mensaje de un cliente en particular)

RESUMEN

Este capitulo muestra que existen dos alternativas a la hora de construir los bloques con los que elaborar los protocolos de internet. Existe una interesante relación de compromiso entre estos dos protocolos: UDP proporciona la posibilidad de un simple paso de mensajes que adolece de fallos de omisión pero lleva asociada penalización en las prestaciones.

En el otro lado, en buenas condiciones, TCP garantiza la entrega de los mensajes pero a cambio de tener mensajes adicionales y una mayor latencia y costos de almacenamiento.

La interfaz del programa de aplicación para UDP proporciona una abstracción del tipo de paso de mensajes, la forma mas simple de comunicación entre procesos. Esto hace que el proceso emisor pueda transmitir un mensaje simple al proceso receptor. Los procesos independientes que contienen estos mensajes se llaman datagramas. Tanto en Java como en cada API UNIX, el emisor especifica el destino utlizando un zocalo , conector o socket(una referencia indirecta a un puerto en particular utlizada por el proceso destino en el computador destino)

La interfaz del programa de aplicación de TCP proporciona la abstracción de un flujo (stream) de dos direcciones enrte pares de procesos. La información intercambiada consiste en un

stream de datos sin limites entre mensajes. Los streams son un bloque básico para la construcción de la comunicación productor consumidor. Un productor y un consumidor forman un par de procesos en los cuales el papel del primero es producir ítems de datos y el papel del segundo es consumir es consumirlos. Los ítems de datos enviados por el productor al consumidor se colocan en una cola a su llegada hasta que el consumidor este en disposición de recibirlos. El consumidor debe esperar cuando no hay datos disponibles y el productor debe esperar si se llena el almacenamiento utilizado para guardar la cola de los Items.

BIBLIOGRAFIA RECOMENDADA

o George Colouris, “Sistemas Distribuidos” Conceptos y

Diseño, Addison Wesley, España 2001

http://www.cdk3.net/

o Tanenbaum, Distributed Systems: Principles and

Paradigms, Prentice Hall, Mexico 2002.

http://www.prenhall.com/divisions/esm/app/author_tanenb aum/custom/dist_sys_1/

o Liu, “Distributed Computing: Principles and

Applications”,

Addison Wesley, Mexico 2005

AUTOEVALUACION FORMATIVA

o Modifique el código de Streams TCP de modo que el

cliente obtenga de forma repetida una línea del usuario y la escriba en el flujo que el servidor leera repetidamente, imprimiendo el resultado de la lectura. Compare los datos enviados utilizando un datgrama UDP y un stream.

o Utilice el código de datagrama UDP para construir un programa cliente que lea repetidamente una línea de entrada del usuario, la envie a un servidor en un datagrama UDP. Y entonces reciba un mensaje del servidor. El cliente asociara un tiempo de espera limite con su conector, de modo qe pueda informar al usuario cuando el servidor no responda.

o Utilice el código de datagrama UDP, para probar el efecto

causado sobre el emisor cuandoel receptor se cae y viceversa.

UNIDAD ACADÉMICA Nº 06

OBJETOS DISTRIBUIDOS

In document Libro Final Sistemas Distribuidos PDF (página 99-111)