Ejemplo UDP en Java
import java.net.*;
import java.io.*;
public class UDPClient {
public static void main(String args[]) {
DatagramSocket socket = null;
try {
socket = new DatagramSocket();
byte[] m = args[0].getBytes();
InetAddress host = InetAddress.getByName(args[1]);
int port = 6789;
DatagramPacket req = new DatagraPacket(m,
args[0].length, host, port);
socket.send(req);
byte[] n = new byte[1000];
DatagramPacket rep = new
DatagraPacket(n, n.length);
socket.receive(rep);
System.out.println(“Received “+ new String
(rep.getData()));
} catch (SocketException e) {
System.out.println(“Socket: “+e.getMessage()); }
} catch (IOException e) {
System.out.println(“IO: “+e.getMessage());}
} finally { if (socket != null) socket.close(); }
}
}
import java.net.*;
import java.io.*;
public class UDPServer {
public static void main(String args[]) {
DatagramSocket socket = null;
try {
socket = new DatagramSocket(6789);
byte[] n = new byte[1000];
while (true) {
DatagramPacket req = new
DatagraPacket(n, n.length);
socket.receive(req);
DatagramPacket rep = new
DatagramPacket(req.getData(),
req.getLength(), req.getAddress(),
req.getPort());
socket.send(rep);
}
} catch (SocketException e) {
System.out.println(“Socket: “+e.getMessage()); }
} catch (IOException e) {
System.out.println(“IO: “+e.getMessage());}
} finally { if (socket != null) socket.close(); }
}
}
Particularidades de UDP
• Tamaño del mensaje: el recibidor debe establecer el largo
del mensaje a recibir, si es más chico que el que se mandó se
trunca (se puede hasta 216 pero muchos ambientes lo limitan
a 8 kilobytes)
• Bloqueo: la instrucción de send no bloquea Los datagramas
son almacenados en una cola en el destino. Si no hay proceso
esperándolos se descartan. Receive bloquea hasta que hay
algo que leer de la cola o hasta el timeout
• Timeouts: se pueden definir sobre el socket, por default no
hay setSoTimeout. Concurrencia ?
• Recibe de cualquiera: el receive no especifica de quién, así
que el origen se saca del datagrama. Se puede abrir un
DatagramSocket que sólo pueda mandar a una dirección y a
un port connect (en qué casos es útil?)
Lo mismo con TCP
import java.net.*;
import java.io.*;
public class TCPClient {
public static void main(String args[]) {
Socket socket = null;
try {
s = new Socket(args[1], 6789);
DataInputStream in = new
DataInputStram(s.getInputStream());
DataOutputStream out = new
DataOutputStream(s.getOutputStream());
out.writeUTF(args[0]);
String data = in.readUTF();
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 (socket != null) try { socket.close(); }
catch(IOException e) {}
}
}
import java.net.*;
import java.io.*;
public class UDPServer {
public static void main(String args[]) {
try {
DataInputStream in = null;
DataOutputStream out = null;
ServerSocket ss = new ServerSocket(6789);
while(true) {
Socket s = ss.accept();
in = new DataInputStream(s.getInputStream());
out = new OutputStream(s.getOutputStream());
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 { if (socket != null) try { socket.close(); }
catch(IOException e) {}
}
}
Particularidades de TCP
• Coincidencia de datos en los extremos :
• Bloqueo: hay chequeo (ack)
• Fallas : TCP trata de hacer coincidir las velocidades de escritura
y lectura. Si el escribidor es muy rápido, trata de bloquearlo hasta
que el lector haya consumido suficiente.
• Duplicación y orden de mensajes: los paquetes ip contienen
identificadores correlativos que permiten al recibidor detectar
duplicados o cambiados de orden
• Destino de los mensajes: como se abre una conexión virtual entre
ambos extremos, no es necesario especificar a quién va ya que el
socket se abre con un connect
Qué esconde TCP
• Tamaño del mensaje: Las aplicaciones deciden cuánto leer y
cuánto escribir. El sistema subyacente decide cómo transmitirlo.
• Mensajes Perdidos: hay chequeo (ack)
• Control de flujo: TCP trata de hacer coincidir las velocidades de
escritura y lectura. Si el escribidor es muy rápido, trata de
bloquearlo hasta que el lector haya consumido suficiente.
• Duplicación y orden de mensajes: los paquetes ip contienen
identificadores correlativos que permiten al recibidor detectar
duplicados o cambiados de orden
• Destino de los mensajes: como se abre una conexión virtual entre
ambos extremos, no es necesario especificar a quién va ya que el
socket se abre con un connect
Problemas de TCP
• Coincidencia de datos: Lo que se mande por un lado y lo que se
lea (formato) debe coincidir (en especial al mandar objetos).
• Bloqueo: hay que asegurarse que cundo se escribe pocos datos
estos se manden si es necesario contar con ellos pronto o pueden
bloquear la ejecución (buffer)
• La comunicación se establece de punto a punto, así que sólo se
atiende a un cliente a la vez (a menos que se haga concurrente)
• Falla de la conexión: si se demora mucho en hacer el ack
entonces la conexión se declara rota (se tira un IOException). En
este sentido TCP no es más seguro de lo que la red lo es.
• El proceso usando la conexión no puede distinguir si la falla se
debe a la red o a que el proceso par se cayó
• No puede saber después de la caída qué llego efectivamente a
destino y qué no alcanzó a llegar
El esquema request-reply
• Muchas veces cuando se usa TCP o UDP se modela el protocolo
de comunicación entre cliente y servidor con el esquema de
request-reply
• Son la base para implementar middleware como RMI, RPC,
CORBA o algo parecido
• Se basan en un trio de primitivas de comunicación: doOperation,
getRequest y sendReply
Cliente
doOperation
(wait)
(continue)
Servidor
getRequest
(select object)
(execute meth.)
sendReplay
El esquema request-reply
• Aunque a Implementación UDP tiene ventajas se han
implementado ya algunas versiones en TCP:
• el acknowladge de TCP es innecesario ya que se hace un reply
a cada request a nivel de aplicación
• se evitan los mensajes para la conexión
• el control de flujo es innecesario cuando los argumentos
pasados son pequeños (caben en una trama)
• Un esquema en Java (Ejemplo)
• public byte[] doOperation(RemoteObjectref o, int methodID,
byte args)
manda una operación sobre un objeto y retorna el reply
• public byte[] getRequest()
recibe un request de un cliente
• public void sendReply(byte[] reply, InetAddress clientHost,
int clientPort)
manda un reply a la dirección y port especificados
Estructura de los mensajes
Tipo de mensaje
requestID
objectReference
methodId
argumentos
int (0 = request, 1 = reply)
int
RemoteObjectRef
int
arreglo de bytes
Representación de una referencia remota de objeto
Internet Address port number time object number interface
Comunicación de Grupo con
Multicast
Provee:
• Tolerancia a fallas basada en la replicidad de servicios: un
servicio replicado consiste en un grupo de servidores. El cliente
manda el request a todos los servidores que realizan la misma
operación.
• Encuentro de servicios de descubrimiento de servidores:
clientes y servidores usan mensajes de multicast para localizar
servicios presentes en la red para poder registrar sus interfaces y
y hacer lookup de interfaces de otros servicios
• Mejor performance por datos replicados: a veces se replican
los datos en los computadores cliente (cache) cuando estos
varían el servidor manda mensajes por multicast
• Propagación de eventos de notificación: para notificar a
procesos interesados en ciertos eventos que estos tuvieron lugar
(jini)
Fallas en Multicast
Ya que se basa en UDP puede pasar :
• Tolerancia a fallas basada en la replicación de servicios: Si los
servidores parten de un mismo estado inicial y se coordinan con
los updates en un orden preciso. Si un miembro no recibe el
update o lo recibe en mal orden se vuelve inconsistente
• Encuentro de servicios de descubrimiento de servidores: esto
no es problema si las peticiones de localización se hacen
reiterativamente en tiempos regulares. Así se hace en Jini
• Mejor performance por datos replicados: si en vez de replicar
operaciones en los datos lo que se replica es el dato mismo, estos
pueden aparecer inconsistentemente en cada servidor
• Propagación de eventos de notificación: El servicio de anuncio
acerca de nuevos servicios en la red provisto por Jini envia
mensajes multicast reiterativos a tiempos regulares
Ejemplo de Multicast en Java
import java.io.*;
import java.io.*;
import java.net.*;
import java.net.*;
public class MulticastClient {
import java.util.*;
public static void main(String[] args) throws IOException {
public class MulticastServer {
MulticastSocket socket = new MulticastSocket(4446);
static public void main(String args[]) {
InetAddress address =
DatagramSocket socket = null;
InetAddress.getByName("224.2.2.3");
BufferedReader in = null;
socket.joinGroup(address);
boolean moreQuotes = true;
byte[] buf = new byte[256];
try {
DatagramPacket packet;
socket = new DatagramSocket();
while (true) {
while(true) {
InetAddress grupo = InetAddress.getByName("224.2.2.3");
packet = new DatagramPacket(buf, buf.length);
for (int i=1; i< 1000; i++) {
socket.receive(packet);
String dString = i+"--"+(InetAddress.getLocalHost());
byte[] buf = dString.getBytes();
String received = new String(packet.getData());
DatagramPacket packet =
System.out.println("Received: " + received);
new DatagramPacket(buf, buf.length, grupo, 4446);
try {
socket.send(packet);
Thread.currentThread().sleep(0); }
try {
catch (InterruptedException e) {
}
Thread.currentThread().sleep(200); }
}
catch (InterruptedException e) {}
}
}
}
} catch (IOException e) {}
}
}
Multicast para grupos
Multicast tiene cualidades que lo hacen más eficiente para
transmitir un mensaje a varios miembros de un grupo
Modelo:
message(g,m) : operación de transmisión de un
mensaje m a los miembros de un grupo g
deliver(m) : operación de proceso de mensaje m
sender(m) : identificación del que manda el mensaje
group(m) : grupo de destino del mensaje
open/closed group : el grupo puede/no puede recibir
mensajes mandados por un por un
miembro que no pertenece al grupo
Reliable Multicast
Reliable multicast implica que se cumplen 3 propiedades:
Integridad: el mensaje que se manda es igual al que se
procesa y que ningún mensaje es procesado dos veces. Un
proceso p hace la operación deliver(m) una sola vez y p 
group(m)
Validez : si un proceso manda un mensaje multicast, tarde
o temprano lo procesará si pertenece al grupo
Agreement : si un proceso procesa un mensaje m el resto
de los miembros del grupo también lo hará
Reliable Multicast con IP !
• Cada proceso p mantiene un número de secuencia S(p,g) para grada
grupo g al que pertenece.
• También mantiene un registro R(q,g) que es el número de secuencia del
último mensaje procesado del proceso q que mandó al grupo g.
• Cuando p quiere mandar un mensaje a g incluye el número S(p,g) y
pares <q,R(q,g)>, luego incrementa S(p,g).
• Un proceso del grupo procesa el mensaje mandado por p sólo si el S =
R(p,g) +1
• Si S <= R(p,g) es un mensaje repetido y lo descarta
• Si S > R(p,g) + 1 significa que perdió un mensaje y manda un ack
negativo para que lo mande de nuevo.
• Integridad se alcanza por la detección de duplicados y los checkeos de
IP en los datagramas. Validez por propiedad de IP. Agreement implica
que los procesos siempre guardan copias de mensajes enviados para
enviarlos de nuevo
• para que esto funcione los proceso no deben fallar !!!!
Ordenando los mensajes de
Multicast
• Se usa un cola de mensajes multicast para guardarlos antes de procesarlos. Se
trata de asignar un número de secuencia para cada mensaje en el cual todos estén
de acuerdo. Cada proceso q en un grupo g mantiene un número A(q,g), el más
grande de la secuencia acordada que se ha observado para un grupo g y P(q,g) el
mayor de la secuencia propia. Cuando p quiere mandar un mensaje:
• Manda en forma segura <m,i> siendo m el mensaje e i un identificador
único para m
• cada proceso q responde a p con una proposición para acordar un número
de secuencia para ese mensaje P(q,g) = Max(A(q,g), P(q,g))+1. Cada
proceso guarda en su cola el mensaje con el número de secuencia que
propuso provisionalmente ordenado de menor a mayor número de secuencia
• p recolecta todos los números de secuencia propuestos y selecciona el
mayor a como el que se usará definitivamente y lo transmite en un mensaje
broadcast seguro <i,a>
• cada proceso entonces ordena la cola de mensajes antes de procesarlos
según los números de secuencia acordados
• ¿ Cómo se puede demostrar que esto es monotonicamente creciente ?
Un chat Basado en Multicast
• Esquema
de arquitectura peer-to-peer, no hay servidor
• Arquitectura replicada
• Comunicación por multicast
• El grupo de chat se define por el número IP de multicast y
el port acordados
• Cada Participante que tiene interés debe abrir un multicast
socket y lanzar/recibir paquetes a esa dirección
• Dos threads: uno para leer líneas del teclado y mandarlas
por el socket y otro para leer datagramas del socket y mostrar
su contenido
• ¿ Cuáles son los problemas y cómo solucionarlos ?
Descargar

Ejemplo UDP en Java