Mensaje de bienvenida Estimado usuario A través de esta Wiki queremos brindarle información con respecto a los Datagramas y algunos temas relacionados a este. Para cualquier información complementaría o comentarios sobre el contenido de este sitio web, no dude informarnos Muchas gracias por su visita a nuestro wiki Los alumnos 1 INDICE Visión general 1 Definición: Concepto y formato. 2 Datagrama UDP 2.1 Visión general 2.2 Clase DatagramPacket 2.3 Clase DatagramSocket 2.4 Escuchar paquetes UDP 2.5 Enviar paquetes UDP 2.6 Ejemplo de protocolo de datagramas de usuario 2.7 Construir un UDP cliente/servidor 2.8 Información adicional sobre UDP 3 Análisis comparativo: TCP – UDP 4 Software de aplicación 5 Bibliografía 2 DATAGRAMAS Visión general Conmutación (redes de comunicación): es la conexión que realizan los diferentes nodos que existen en distintos lugares y distancias para lograr un camino apropiado para conectar dos usuarios de una red de telecomunicaciones. La conmutación permite la descongestión entre los usuarios de la red disminuyendo el tráfico y aumentando el ancho de banda. Figura Nº 1: Redes de comunicación 3 Conmutación de circuitos. Es aquella en la que los equipos de conmutación deben establecer un camino físico entre los medios de comunicación previa a la conexión entre los usuarios. Este camino permanece activo durante la comunicación entre los usuarios, liberándose al terminar la comunicación. Ejemplo: Red Telefónica Conmutada. Su funcionamiento pasa por las siguientes etapas: solicitud, establecimiento, transferencia de archivos y liberación de conexión. Figura Nº 2: Red de conmutación de circuitos Conmutación de mensajes Este método era el usado por los sistemas telegráficos, siendo el más antiguo que existe. Para transmitir un mensaje a un receptor, el emisor debe enviar primero el mensaje completo a un nodo intermedio el cual lo encola en la cola donde almacena los mensajes que le son enviados por otros nodos. Luego, cuando llega su turno, lo reenviará a otro y éste a otro y así las veces que sean necesarias antes de llegar al receptor. El mensaje deberá ser almacenado por completo y de forma temporal en el nodo intermedio antes de poder ser reenviado al siguiente, por lo que los nodos temporales deben tener una gran capacidad de almacenamiento 4 Figura Nº 3: Red de conmutación de mensaje Conmutación de paquetes El emisor divide los mensajes a enviar en un número arbitrario de paquetes del mismo tamaño, donde adjunta una cabecera y la dirección origen y destino así como datos de control que luego serán transmitidos por diferentes medios de conexión entre nodos temporales hasta llegar a su destino. Este método de conmutación es el que más se utiliza en las redes de ordenadores actuales. Surge para optimizar la capacidad de transmisión a través de las líneas existentes. Al igual que en la conmutación de mensajes, los nodos temporales almacenan los paquetes en colas en sus memorias que no necesitan ser demasiado grandes. Figura Nº 4: Red de conmutación de paquetes 5 Las redes actuales utilizan el packet switching (Conmutación de paquetes) para la transferencia de datos. Los datos se envuelven en paquetes que se transfieren desde un origen a un destino, donde se extraen de uno en uno los datos de uno o más paquetes para reconstruir el mensaje original. Los nodos que se comunican a través de Internet utilizan principalmente dos protocolos: TCP - Transsmision Control Protocol UDP - (Universal / User) Datagram Protocol Los datagramas IP son las unidades principales de información de Internet. Los términos trama mensaje paquete de red y segmento también se usan para describir las agrupaciones de información lógica en las diversas capas del modelo de referencia OSI y en los diversos círculos tecnológicos. 6 1. Definición: Concepto y estructura Definición Un datagrama es un fragmento de paquete (análogo a un telegrama) que es enviado con la suficiente información para que la red pueda simplemente encaminar el fragmento hacia el equipo terminal de datos receptor, de manera independiente a los fragmentos restantes. Esto puede provocar una recomposición desordenada o incompleta del paquete en el ETD destino. Figura Nº 5: Protocolo UDP Los datagramas también son la agrupación lógica de información que se envía como una unidad de capa de red a través de un medio de transmisión sin establecer con anterioridad un circuito virtual. Los datagramas IP son las unidades principales de información de Internet. Los términos trama, mensaje, paquete y segmento también se usan para describir las agrupaciones de información lógica en las diversas capas del modelo de referencia OSI y en los diversos círculos tecnológicos. Algunos Protocolos basados en datagramas son IPX, UDP, IPoAC. Los datagramas tienen cabida en los servicios de red no orientados a la conexión (como por ejemplo UDP) o Datagrama. 7 El protocolo Intercambio de Paquetes Entre Redes (IPX) es la implementación del protocolo IDP (Internet Datagram Protocol) de Xerox. Es un protocolo de datagramas rápido orientado a comunicaciones sin conexión que se encarga de transmitir datos a través de la red, incluyendo en cada paquete la dirección de destino. IPX Pertenece a la capa de red (nivel 3 del modelo OSI) y al ser un protocolo de datagramas es similar (aunque más simple y con menor fiabilidad) al protocolo IP del TCP/IP en sus operaciones básicas pero diferente en cuanto al sistema de direccionamiento, formato de los paquetes y el ámbito general Fue creado por el ing. Alexis G.Soulle UDP User Datagram Protocol (UDP) es un protocolo del nivel de transporte basado en el intercambio de datagramas (Paquete de datos). Permite el envío de datagramas a través de la red sin que se haya establecido previamente una conexión, ya que el propio datagrama incorpora suficiente información de direccionamiento en su cabecera. Tampoco tiene confirmación ni control de flujo, por lo que los paquetes pueden adelantarse unos a otros; y tampoco se sabe si ha llegado correctamente, ya que no hay confirmación de entrega o recepción. Su uso principal es para protocolos como DHCP, BOOTP, DNS y demás protocolos en los que el intercambio de paquetes de la conexión/desconexión son mayores, o no son rentables con respecto a la información transmitida, así como para la transmisión de audio y vídeo en tiempo real, donde no es posible realizar retransmisiones por los estrictos requisitos de retardo que se tiene en estos casos. IPoAC IP sobre palomas mensajeras es un protocolo de red creado en 1 de abril de 1990 para la transmisión de datagramas del protocolo IP mediante palomas mensajeras y definido en la recomendación RFC 1149. El 1 de abril de 1999 se publicó la recomendación RFC 2549, una extensión de la anterior denominada IP sobre palomas mensajeras con calidad de servicio. 8 Estructura La estructura de un datagrama es: cabecera y datos. Figura Nº 6: Estructura de un datagrama Significado de los diferentes campos Puerto de origen: es el número de puerto relacionado con la aplicación del remitente del segmento UDP. Este campo representa una dirección de respuesta para el destinatario. Por lo tanto, este campo es opcional. Esto significa que si el puerto de origen no está especificado, los 16 bits de este campo se pondrán en cero. En este caso, el destinatario no podrá responder (lo cual no es estrictamente necesario, en particular para mensajes unidireccionales). Puerto de destino: este campo contiene el puerto correspondiente a la aplicación del equipo receptor al que se envía. Longitud: este campo especifica la longitud total del segmento, con el encabezado incluido. Sin embargo, el encabezado tiene una longitud de 4 x 16 bits (que es 8 x 8 bits), por lo tanto la longitud del campo es necesariamente superior o igual a 8 bytes. Suma de comprobación: es una suma de comprobación realizada de manera tal que permita controlar la integridad del segmento. Enrutamiento Enrutar es el proceso de selección de un camino para el envío de paquetes. La computadora que hace esto es llamada Router. 9 Figura Nº 7: Enrutamiento En general se puede dividir el enrutamiento en Entrega Directa y Entrega Indirecta. La Entrega Directa es la transmisión de un Datagrama de una maquina a otra dentro de la misma red física. La Entrega Indirecta ocurre cuando el destino no está en la red local, lo que obliga al Host a enviar el Datagrama a algún Router intermedio. Es necesario el uso de mascaras de subred para saber si el Host destino de un Datagrama esta o no dentro de la misma red física. Algoritmo de Enrutamiento Ruta Datagrama(Datagrama) { Extrae de la Cabecera de Datagrama la dirección de destino D; Extrae de D el prefijo de Red N; Si N corresponde a cualquier dirección directamente conectada Entonces Envía el Datagrama a D sobre la Red N; Sino Si en la tabla hay una ruta especifica para D Entonces Envía Datagrama al salto siguiente especificado; Sino Si En la tabla hay una ruta para la red N Entonces Envía Datagrama al salto siguiente especificado; Sino Si En la tabla hay una ruta por defecto Entonces Envía el Datagrama a la dirección por defecto; Sino Declarar Fallo de Enrutamiento; Fsi Fsi Fsi Fsi } 10 Puertos UDP utiliza puertos para permitir la comunicación entre aplicaciones. El campo de puerto tiene una longitud de 16 bits, por lo que el rango de valores válidos va de 0 a 65.535. El puerto 0 está reservado, pero es un valor permitido como puerto origen si el proceso emisor no espera recibir mensajes como respuesta. Los puertos 1 a 1023 se llaman puertos "bien conocidos" y en sistemas operativos tipo Unix enlazar con uno de estos puertos requiere acceso como superusuario. Los puertos 1024 a 49.151 son puertos registrados. Los puertos 49.152 a 65.535 son puertos efímeros y son utilizados como puertos temporales, sobre todo por los clientes al comunicarse con los servidores. 2. User Datagram Protocol (UDP) 2.1 Visión general El protocolo UDP (User Datagram Protocol) es un protocolo no orientado a conexión de la capa de transporte del modelo TCP/IP, lo que significa que no garantizar ni la entrega de paquetes ni que los paquetes lleguen en orden secuencial, donde el control sobre el destino final de un paquete UDP recae en el equipo que lo envía. 11 Figura Nº 7: UDP en una red pueden ser poco fiables Dado la probabilidad de pérdida de paquetes de datos, puede parecer extraño que a nadie se le ocurra utilizar un sistema tan poco fiable, aparentemente anárquica. De hecho, hay muchas ventajas al usar UDP que pueden no ser evidentes a primera vista. UDP puede ser más eficiente que la entrega garantizada de flujos de datos de. Si la cantidad de datos es pequeña y los datos se envían con frecuencia, tiene sentido usarla para evitar la sobrecarga de entrega garantizada. A diferencia de TCP, que establecen una conexión, UDP causa menos gastos generales. Si la cantidad de datos que se envían es pequeña y los datos se envían con frecuencia, la sobrecarga de establecer una conexión no puede valer la pena. UDP puede ser preferible en este caso, sobre todo si se envían los datos de un gran número de máquinas a una central, en cuyo caso la suma total de todas estas conexiones pueden provocar una sobrecarga considerable. Las aplicaciones en tiempo real pueden ser candidatos para usar UDP, ya que hay menos retrasos debido a la comprobación de errores y control de flujo de TCP. Los 12 Paquetes UDP pueden ser utilizados para saturar el ancho de banda disponible para ofrecer grandes cantidades de datos. Además, si se pierden algunos datos, pueden ser sustituidos por el siguiente grupo de paquetes con información actualizada, eliminando la necesidad de volver a enviar los datos antiguos. Los sockets UDP puede recibir datos de más de un host. Si hay varias máquinas debe haber comunicación, entonces UDP puede ser más conveniente que otros mecanismos como TCP. Algunos protocolos de red especificar UDP como mecanismo de transporte, que requiriendo su uso. Un socket es una referencia indirecta a un puerto particular usada por el proceso receptor en la máquina receptora. El envío de datagramas es similar a enviar una carta a través del servicio postal: El orden de salida no es importante y no está garantizado, y cada mensaje es independiente de cualquier otro. En las comunicaciones basadas en datagramas como las UDP, el paquete de datagramas contiene el número de puerto de su destino y el UDP encamina el paquete a la aplicación apropiada. Como en la figura Nº 8 Figura Nº 8: Comunicación basada en datagramas 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 una dirección de Internet y un puerto local. Un servidor enlazará ese socket a un puerto servidor - uno que se hace conocido a los clientes de 13 manera que puedan enviar mensajes al mismo. Un cliente enlaza su socket a cualquier puerto local libre. El método receptor devuelve la dirección de Internet y el puerto del emisor, además del mensaje, permitiendo a los receptores enviar una respuesta. Figura Nº 9: un servidor utiliza dos sockets: uno para aceptar la conexión y el otro para enviar / receptor Las clases Java para establecer comunicaciones mediante datagramas son: java.net.DatagramPacket java.net.DatagramSocket 2.2 Clase DatagramPacket La clase DatagramPacket representa un paquete de datos destinados a la transmisión mediante el uso de UDP. Los paquetes son contenedores de una pequeña secuencia de bytes, e incluyen información de direccionamiento, como una dirección IP y un puerto. 14 Figura Nº 10: DatagramPacket El significado de los datos almacenados en un DatagramPacket está determinado por su contexto. Cuando un DatagramPacket se ha leído desde un socket UDP, la dirección IP del paquete representa la dirección del remitente (lo mismo con el número de puerto). Sin embargo, cuando un DatagramPacket es usado para enviar un paquete UDP, la dirección IP almacenada en DatagramPacket representa la dirección del destinatario (lo mismo con el número de puerto). Esta inversión de sentido es importante Recuerde uno no querrá enviar un paquete de regreso a uno mismo! 2.2.1 Creando un DatagramPacket Hay dos razones para crear un nuevo DatagramPacket: I. Para enviar datos a una máquina remota usando UDP II. Para recibir los datos enviados por una máquina remota usando UDP La clase DatagramPacket proporciona un constructor que permite crear instancias de un array de bytes parar: el mensaje, la longitud del mensaje, la dirección Internet y el puerto local del socket de destino, de la siguiente forma: Constructores La elección del constructor DatagramPacket es determinada por su finalidad. 15 Cada constructor requiere la especificación de un conjunto de bytes, el cual se utilizará para almacenar el contenido del paquete UDP, y la longitud del paquete de datos. Para crear un DatagramPacket para la recepción de paquetes UDP entrantes, el siguiente constructor debe ser usado: DatagramPacket(byte[] buffer, int length). Por ejemplo: DatagramPacket packet = new DatagramPacket(new byte[256], 256); Para enviar un DatagramPacket a una máquina remota, es preferible utilizar el siguientes constructor: DatagramPacket(byte[] buffer, int length, InetAddress dest_addr, int dest_port). Por ejemplo: InetAddress addr = InetAddress.getByName("192.168.0.1"); DatagramPacket packet = new DatagramPacket ( new byte[128], 128, addr, 2000); 2.2.2 Usando un DatagramPacket La clase DatagramPacket proporciona algunos métodos importantes que permiten a: la dirección remota, puerto remoto, los datos (como un bytes de array), y la longitud del paquete puedan ser recuperado. A partir de JDK 1.1, hay también métodos para modificar estos, a través de un método set correspondiente. Esto significa que uno recibe paquetes que puedan ser reutilizados. Por ejemplo, el contenido de un paquete puede ser reemplazado y enviado de vuelta al remitente. Esto ahorra el tener que reiniciar la información de direccionamiento, la dirección y el puerto del paquete que ya está establecido en el remitente Métodos InetAddress getAddress() - devuelve la dirección IP desde que un DatagramPacket fue enviado, o (si el paquete va a ser enviado a una máquina remota), la dirección IP de destino. byte [] getData () - devuelve el contenido de la DatagramPacket, representado como una matriz de bytes. int getLength int () - devuelve la longitud de los datos almacenados en un DatagramPacket. Esto puede ser menor que el tamaño real del búfer de datos int getPort () - devuelve el número de puerto desde donde se envió un DatagramPacket, o (si el paquete va a ser enviado a una máquina remota), el número de puerto de destino. 16 void setAddress (InetAddress addr) - asigna una nueva dirección de destino a un DatagramPacket. void setData (byte [] buffer) - asigna un buffer de datos nuevos a la DatagramPacket. void SetLength (int length) - asigna una nueva longitud de la DatagramPacket. Void setPort (int port) - asigna un puerto de destino a un nuevo DatagramPacket. 2.3 Clase DatagramSocket La clase DatagramSocket proporciona acceso a un socket UDP, lo que permite que los paquetes UDP puedan ser enviados y recibidos. Un DatagramPacket se utiliza para representar un paquete UDP, y debe ser creado antes de recibir los paquetes. El mismo DatagramSocket puede ser usado para recibir los paquetes tanto como para enviarlos. Sin embargo, las operaciones de lectura son de bloqueo, lo que significa que la aplicación continuara esperando hasta que llega un paquete. Ya que los paquetes UDP no garantizan la entrega, esto puede causar que una aplicación se detenga si el remitente no vuelva a enviar los paquetes. Ya que los paquetes UDP no garantizan la entrega, esto puede originar que una aplicación se detenga si el remitente no vuelva a enviar los paquetes 2.3.1 Creando un DatagramSocket A DatagramSocket puede ser utilizado para enviar y recibir paquetes. Cada DatagramSocket se une a un puerto en la máquina local, el cual es usado para dirigir a los paquetes. El número de puerto necesita no ser el mismo número de la máquina remota, pero si la aplicación es un servidor UDP, se suelen elegir un número de puerto específico. Si el DatagramSocket está destinado a ser un cliente, y no necesita que se una a un número de puerto específico, un constructor en blanco puede ser especificado. Constructor Para crear un DatagramSocket cliente, el siguiente constructor es usado: DatagramSocket () throws java.net.SocketException. Para crear un server Datagram Socket, el siguiente constructor es usado: que toma como parámetro el puerto al que el servicio UDP será obligado: DatagramSocket (int puerto) throws java.net.SocketException 17 2.3.2 Usando un DatagramSocket DatagramSocket se utiliza para recibir los paquetes UDP entrantes y salientes para enviar paquetes UDP. Proporciona métodos para enviar y recibir paquetes, así también como especificar un valor de tiempo de espera cuando nonblocking I/O está utilizando, para inspeccionar y modificar el máximo tamaño de los paquetes UDP, y cerca del zócalo. Métodos void close () - cierra un socket, y se desliga del puerto local. void connect (InetAddress remote_addr remote_port int) – restringe el acceso a la dirección especificada a distancia y el puerto. La designación es un término equivocado, ya que UDP en realidad no crear una "conexión" entre una máquina y otra. Sin embargo, si este método se utiliza, hace que las excepciones que se produce si se intenta enviar paquetes a,o leer los paquetes de cualquier otro host y el puerto a los especificados. void disconnect() - desconecta el DatagramSocket. InetAddress getInetAddress () - Devuelve la dirección remota a la que el socket está conectado, o null si no existe ninguna tal conexión. int getPort () - devuelve el puerto remoto al que está conectado el socket, o -1 si no existe dicha conexión. InetAddress getLocalAddress () - devuelve la dirección local a la que el socket esta enlazado. int getLocalPort () - devuelve el puerto local al que está enlazado el conector. int getReceiveBufferSize () throws java.net.SocketException – devuelve el tamaño máximo del búfer utilizado para los paquetes UDP entrantes. int getSendBufferSize () throws java.net.SocketException - devuelve el tamaño máximo de búfer utilizado para paquetes UDP salientes. getSoTimeout int () throws java.net.SocketException - devuelve el valor de la opción de conector de tiempo de espera. Este valor se utiliza para determinar el número de milisegundos que una operación de lectura bloqueara antes de lanzar un java.io.InterruptedIOException. De manera predeterminada, este valor será igual a cero, lo que indica que el bloqueo de E / S se utilizará. void receive (DatagramPacket packet)) throws java.io.IOException- lee un paquete UDP y almacena el contenido en el paquete especificado. La dirección y el puerto. 18 2.4 Escuchar paquetes UDP Antes de que una aplicación pueda leer los paquetes UDP enviados por equipos remotos, esta debe de estar vinculada a un puerto UDP local utilizando DatagramSocket, y crear un DatagramPacket que actuará como un contenedor de datos del paquete UDP. La figura muestra la relación entre un paquete UDP, y las diferentes clases de Java utilizada para el proceso, y la aplicación real. Figura Nº 11: Los paquetes UDP son recibidos por un DatagramSocket y se traducen en objeto DatagramPacket. Cuando una aplicación quiere leer los paquetes UDP, llama al método DatagramSocket.receive, que copia un paquete UDP en el DatagramPacket especifico. El contenido de la DatagramPacket es procesado y el proceso se repite según sea necesario. El siguiente fragmento de código ilustra este proceso: DatagramPacket packet = new DatagramPacket (new byte[256], 256); DatagramSocket socket = new DatagramSocket(2000); boolean finished = false; while (! finished ) { socket.receive (packet); // process the packet } socket.close(); Cuando se procesa el paquete, la aplicación debe trabajar directamente con un array de bytes. Sin embargo, si la aplicación se adecua más a la lectura de textos, se puede utilizar las clases del paquete de Java I/O para convertir un array de bytes a otro tipo de stream o lector. Al conectar un ByteArrayInputStream con el contenido de un datagrama y luego a otro tipo de InputStream o un InputStreamReader, se puede acceder al contenido de los 19 paquetes UDP con relativa facilidad. Muchos desarrolladores prefieren usar los stream de Java I/O para procesar data, usando un DataInputStream o un BufferedReader para acceder al contenido de las matrices de bytes. Figura Nº 12: La lectura de un paquete UDP se ha simplificado mediante la aplicación de los streams de entrada. Por ejemplo, para conectar un DataInputStream con el contenido de un DatagramPacket, el siguiente código puede ser usado : ByteArrayInputStream bin = new ByteArrayInputStream( packet.getData() ); DataInputStream din = new DataInputStream (bin); // Read the contents of the UDP packet ....... 20 Figura Nº 13: Las estructuras de datos en los programas de emisor y receptor El flujo del programa en el emisor y receptor Remitente del programa Receptor del programa 1. Crear un socket de datagramas y vincularlo o cualquier puerto local. 2. Colocar la data en una matriz de bytes. 3. Crear un paquete de datagramas, especificando la matriz de datos y la dirección del receptor. 4. Invocar el método de envío del socket con una referencia al paquete de datagramas. 1. Crear un socket de datagrama y enlazarlo a un puerto local específico. 2. Crear una matriz de bytes para la recepción de los datos. 3. Crear un paquete de datagramas, especificando la matriz de datos. 4. Invocar el método de recepción del socket con una referencia a los paquetes de datagramas. 21 2.5 Enviar paquetes UDP La misma interfaz (DatagramSocket) empleada para recibir paquetes UDP también se utiliza para enviarlos. Cuando se envía un paquete, la aplicación debe crear un DatagramPacket, establecer la dirección y el puerto de la información, y escribir los datos destinados a la transmisión a su array de bytes. Si está respondiendo a un paquete recibido, la dirección y la información del puerto ya estará almacenada, y sólo los datos necesitan ser sobrescritos. Una vez que el paquete está listo para la transmisión, el método de envío de DatagramSocket es invocado, y un paquete UDP se envía El siguiente fragmento de código ilustra este proceso: DatagramSocket socket = new DatagramSocket(2000); DatagramPacket packet = new DatagramPacket (new byte[256], 256); packet.setAddress ( InetAddress.getByName ( somehost ) ); packet.setPort ( 2000 ); boolean finished = false; while !finished ) { // Escribir datos en el buffer del paquete ......... socket.send (packet); / / Hacer otra cosa, como leer los paquetes, o revisar para / / ver si hay más paquetes a enviar ......... } socket.close(); 2.6 Ejemplo de protocolo de datagramas de usuario Para demostrar cómo los paquetes UDP se envían y reciben, vamos a compilar y ejecutar dos pequeños ejemplos. El primero se enlazará a un puerto local, leerá un paquete, y mostrará su contenido e información de direccionamiento. El segundo ejemplo enviará el paquete leído por el primero. 22 Código de PacketReceiveDemo import java.net.*; import java.io.*; // Capítulo 5, Listado 1 public class PacketReceiveDemo { public static void main (String args[]) { try { System.out.println ("Enlazandose a puerto local 2000"); // Se crea un socket de datagrama, con destino al // puerto específico 2000 DatagramSocket socket = new DatagramSocket(2000); System.out.println ("Enlazado a puerto local " + socket.getLocalPort()); // Se crea un paquete de datagramas, que contiene un // buffer máximo de 256 bytes DatagramPacket packet = new DatagramPacket( new byte[256], 256 ); // Recibe un paquete - recordar por defecto // esta es una operación de bloqueo socket.receive(packet); System.out.println ("¡Paquete recibido!"); // Muestra la información del paquete InetAddress remote_addr = packet.getAddress(); System.out.println ("Enviado por : " + remote_addr.getHostAddress() ); System.out.println ("Enviado desde: " + packet.getPort()); // Mostrar contenido del paquete, mediante la lectura // del array de bytes ByteArrayInputStream bin = new ByteArrayInputStream (packet.getData()); // Mostrar sólo hasta la longitud del 23 // paquete UDP original for (int i=0; i < packet.getLength(); i++) { int data = bin.read(); if (data == -1) break; else System.out.print ( (char) data) ; } socket.close(); } catch (IOException ioe) { System.err.println ("Error - " + ioe); } } } Cómo funciona PacketReceiveDemo La mayoría del código se explica por sí mismo, o es similar a los fragmentos de código anterior. Sin embargo, los lectores pueden beneficiarse de un examen más detenido. La aplicación se inicia mediante el enlace a un puerto específico, 2000. Las aplicaciones que ofrecen un servicio generalmente se enlazan a un puerto específico. Cuando actúa como un receptor, tu aplicación debe elegir un número de puerto específico, por lo que el emisor puede enviar paquetes UDP a este puerto. A continuación, la aplicación elabora un DatagramPacket para el almacenamiento de los paquetes UDP, y crea un nuevo buffer para almacenar los paquetes de datos. // Se crea un DatagramSocket, con destino al puerto específico 2000 DatagramSocket socket = new DatagramSocket (2000); System.out.println ("Enlazado a un puerto local" + socket.getLocalPort ()); // Se crea un paquete de datagramas, que contiene un buffer máximo de 256 // bytes DatagramPacket packet = new DatagramPacket (new byte [256], 256 ); 24 Ahora la aplicación está lista para leer un paquete. La operación de lectura está bloqueando, por lo que hasta que un paquete llega, el servidor espera. Cuando un paquete es entregado con éxito a la aplicación, la información de direccionamiento para el paquete se muestra de manera que se puede determinar de dónde vino. // Recibir un paquete - recordar por defecto, ésta es una operación // de bloqueo socket.receive (packet); // Muestra la información de paquete InetAddress remote_addr packet.getAddress = (); System.out.println ("Enviado por:" + remote_addr.getHostAddress ()); System.out.println ("Enviar a:" + packet.getPort ()); Para facilitar el acceso a los contenidos del paquete UDP, la aplicación utiliza un ByteArrayInputStream para leer en el paquete. Leyendo un carácter a la vez, el programa muestra el contenido del paquete y luego termina. Tenga en cuenta que los caracteres Unicode, que son representados por algo más que un solo byte, no se pueden escribir de esta manera. // Mostrar contenido del paquete, mediante la lectura del array de bytes ByteArrayInputStream bin = new ByteArrayInputStream (Packet.getData ()); // Mostrar sólo hasta la longitud del paquetes UDP original for (int i = 0; i <packet.getLength (); i++) { int data = bin.read (); if (data == -1) break; else System.out.print ((char) data); } Código para PacketSendDemo import java.net.*; import java.io.*; // Capitulo 5, listado 2 public class PacketSendDemo { public static void main (String args[]) { int argc = args.length; // Comprobar un número válido de parámetros if (argc != 1) { 25 System.out.println ("Sintaxis :"); System.out.println ("nombre del host java PacketSendDemo"); return; } String hostname = args[0]; try { System.out.println ("Enlazando a un Puerto local"); // Crear un datagram socket, enlazar a cualquier // puerto local disponible DatagramSocket socket = new DatagramSocket(); System.out.println ("Enlazado a Puerto local " + socket.getLocalPort()); // Crear un mensaje para enviar usando un paquete UDP ByteArrayOutputStream bout = new ByteArrayOutputStream(); PrintStream pout = new PrintStream (bout); pout.print ("¡Saludos!"); // Obtener los contenidos de nuestro mensaje como un array // de bytes byte[] barray = bout.toByteArray(); // Crear un paquete de datagrama, conteniendo nuestro // arreglo de bytes DatagramPacket packet = new DatagramPacket( barray, barray.length ); System.out.println ("Buscando nombre de host " + hostname ); // Buscando el nombre de host especificado, y obtener una // InetAddress InetAddress remote_addr = InetAddress.getByName(hostname); System.out.println ("Nombre de host resuelto como " + remote_addr.getHostAddress()); // Direccionar paquete a remitente packet.setAddress (remote_addr); // Establecer número de Puerto en 2000 packet.setPort (2000); // Enviar el paquete – recordar que no garantiza la entrega socket.send(packet); 26 System.out.println ("Paquete enviado!"); } catch (UnknownHostException uhe) { System.err.println ("No se puede encontrar el host " + hostname); } catch (IOException ioe) { System.err.println ("Error - " + ioe); } } } Cómo funciona PacketSendDemo El segundo ejemplo utiliza UDP para comunicarse con el primer ejemplo. Este ejemplo actúa como el remitente, enviando un paquete UDP al receptor, que contiene un mensaje de felicitación en texto ASCII. A pesar de que utiliza algunas clases similares (DatagramSocket, DatagramPacket), estas son empleadas de una manera ligeramente diferente. La aplicación se inicia enlazando un socket UDP a un puerto local, que se utilizará para enviar el paquete de datos. A diferencia de la demostración del receptor, no importa que puerto local se está utilizando. De hecho, cualquier puerto libre es un candidato, y es posible que la ejecución de la aplicación varias veces resultara en números de puerto diferentes. Después de enlazarse a un puerto, el número de puerto se muestra para demostrarlo. / / Se crea un socket de datagramas, con destino a cualquier puerto local disponible 27 DatagramSocket socket = new DatagramSocket(); System.out.println ("Enlazado a Puerto local " + socket.getLocalPort()); Antes de enviar los datos, necesitamos crear un DatagramPacket. En primer lugar, un ByteArrayOutputStream es utilizado para crear una secuencia de bytes. Una vez completado esto, el array de bytes se pasa al constructor DatagramPacket. / / Crear un mensaje para enviar utilizando un paquete UDP ByteArrayOutputStream bout = new ByteArrayOutputStream(); PrintStream pout = new PrintStream (bout); pout.print ("Saludos!"); / / Obtener el contenido de nuestro mensaje como un array de bytes byte[] barray = bout.toByteArray(); / / Se crea un paquete datagrama, que contiene nuestro array de bytes DatagramPacket packet = new DatagramPacket( barray, barray.length ); Ahora que el paquete tiene algunos datos, necesita ser direccionado correctamente. Al igual que con un mensaje de correo, si carece de información correcta sobre la dirección no se puede entregar. Empezamos por obtener una InetAddress de la máquina remota, y luego mostrar su dirección IP. Este es InetAddress es pasado al método setAddress de DatagramPacket, asegurando que llegará a la máquina correcta. Sin embargo, debemos ir un paso más allá y especificar un número de puerto. En este caso, el puerto 2000 coincide, ya que el receptor estará enlazado a ese puerto. 28 System.out.println ("Buscando nombre de host" + hostname); // Lookup the specified hostname, and get an InetAddress InetAddress remote_addr = InetAddress.getByName(hostname); System.out.println ("Nombre de host resuelto como" + remote_addr.getHostAddress()); / / Direccionar paquete al remitente packet.setAddress (remote_addr); / / Establecer el número de puerto en 2000 packet.setPort (2000); El paso final, después de todo este trabajo, es enviar el paquete. Este es el paso más sencillo de todos, simplemente invocar el método de envío de DatagramSocket. Una vez más, recuerde: no hay ninguna garantía de entrega, así que es posible que un paquete se pierda en el tránsito. Una aplicación más robusta intentaría leer un acuse de recibo y reenviar el mensaje si se hubiera perdido. / / Envía el paquete - recuerde que no garantiza la entrega socket.send(packet); Ejecución de los ejemplos UDP Para ejecutar estos ejemplos, usted tendrá que abrir dos ventanas de la consola. La primera aplicación que se ejecuta es el receptor, que se espera por un paquete UDP. No hay parámetros para el receptor, por lo que para ejecutarlo utiliza: java PacketReceiveDemo En una segunda ventana, a continuación, deberá ejecutar el remitente. Esta aplicación se puede ejecutar desde cualquier ordenador en una red local o Internet (siempre que no haya un firewall entre los dos hosts). Si lo desea, también puede ejecutar desde la misma máquina. Se requiere un solo parámetro, el nombre de host de la máquina remota: java PacketSendDemo myhostname NOTA Como se ha mencionado en capítulos anteriores, puede utilizar localhost como nombre de host para referirse a la máquina local. 29 2.7 Construir un UDP cliente/servidor El ejemplo previo ilustra los detalles técnicos de cómo un paquete individual puede ser enviado y recibido. Las aplicaciones necesitan una serie de paquetes, no sólo uno. El siguiente ejemplo muestra cómo construir un servidor UDP, un sistema de larga data que es capaz de servir muchas solicitudes durante su tiempo de vida. El tipo de servidor que se brinda es un servicio eco, que hace eco de los contenidos de un paquete. El servicio de eco corre en un puerto bien conocido, el puerto 7, y si se sabe que un sistema tiene un servidor eco instalado, el servidor podría ser accedido por los clientes para ver si un sistema está levantado y corriendo (similar a la aplicación ping). El ejemplo de abajo demuestra cómo escribir un cliente eco que enviará paquetes al servidor así como leerá los resultados devueltos. NOTA Algunos sistemas ya tienen el servicio eco corriendo en segundo plano, y restricciones de seguridad pueden prevenir que el servicio se enlace a un Puerto bien conocido. Si este es el caso, necesitaras cambiar el número de puerto a uno diferente (en el caso de restricciones de seguridad, debes seleccionar un numero por encima del 1024) en el cliente y el servidor. El mismo número de puerto debe ser usado para la comunicación. 2.7.1 Construyendo un servicio de eco El siguiente ejemplo involucra construir un servicio de eco, que transmite de vuelta al origen cualquier paquete que recibe. El código no usa ninguna clase o método nuevo, pero emplea una técnica especial. Hace un bucle continuo para servir a un cliente después de otro. A pesar de que solo se puede procesar un paquete a la vez, el retardo entre recibir un paquete y despacharlo otra vez es despreciable, lo que resulta en la ilusión de procesamiento concurrente. 30 import java.net.*; import java.io.*; // Capitulo 5, listado 3 public class EchoServer { // Puerto UDP al cual se enlaza el servicio public static final int SERVICE_PORT = 7; // tamaño maximo del paquete, lo suficientemente largo para casi cualquier cliente public static final int BUFSIZE = 4096; // Socket usado para leer y escribir paquetes UDP private DatagramSocket socket; public EchoServer() { try { // enlazarse al puerto UDP especificado para escuchar paquetes de datos entrantes socket = new DatagramSocket( SERVICE_PORT ); System.out.println ("Servicio activo en el puerto " + socket.getLocalPort() ); } catch (Exception e) { System.err.println ("No se puede enlazar el puerto"); } } public void serviceClients() { // Create a buffer large enough for incoming packets byte[] buffer = new byte[BUFSIZE]; for (;;) { try { // Crear un DatagramPacket para leer paquetes UDP DatagramPacket packet = new DatagramPacket ( buffer, BUFSIZE ); // Recibir paquetes entrantes socket.receive(packet); System.out.println ("Paquete recibido de " + packet.getAddress() + ":" + 31 packet.getPort() + " of length " + packet.getLength() ); // eco del paquete, dirección y puerto // ya está establecido! socket.send(packet); } catch (IOException ioe) { System.err.println ("Error : " + ioe); } } } public static void main(String args[]) { EchoServer server = new EchoServer(); server.serviceClients(); } } 2.7.2 Construyendo un cliente de eco El siguiente cliente puede ser utilizado con el servicio eco y puede ser adaptado fácilmente para soportar otros servicios. Se envían paquetes repetidos al servicio eco, y se tiene un timeout para prevenir que el servicio se plante si un paquete se pierde, y el cliente luego espera recibirlo. Recuerde que es poco probable que un paquete se pierda en el entorno de una intranet, pero con conexiones de red lentas en la internet es muy posible. 32 import java.net.*; import java.io.*; // Capitulo 5, Listado 4 public class EchoClient { // Puerto UDP al cual se enlaza el servicio public static final int SERVICE_PORT = 7; // tamaño maximo del paquete public static final int BUFSIZE = 256; public static void main(String args[]) { //nombre del host String hostname = "localhost"; // Conseguir una InetAddress para el nombre de host especificado InetAddress addr = null; try { // Resolver el nombre de host a una dirección Inet addr = InetAddress.getByName(hostname); } catch (UnknownHostException uhe) { System.err.println ("No se puede resolver el host"); return; } try { // Enlazarse a cualquier puerto libre DatagramSocket socket = new DatagramSocket(); // Establecer un valor de timeout de 2 segundos socket.setSoTimeout (2 * 1000); for (int i = 1 ; i <= 10; i++) { // Copiar algunos datos a nuestro paquete String message = "Numero de paquete " + i ; char[] cArray = message.toCharArray(); byte[] sendbuf = new byte[cArray.length]; for (int offset = 0; offset < cArray.length ; offset++) { 33 sendbuf[offset] = (byte) cArray[offset]; } // Crear un paquete para enviar al servidor UDP DatagramPacket sendPacket = new DatagramPacket(sendbuf, cArray.length, addr, SERVICE_PORT); System.out.println ("Enviando paquete a: " + hostname); // Enviar el paquete socket.send (sendPacket); System.out.print ("Esperando el paquete… "); // Crear un pequeño paquete para recibir UDP byte[] recbuf = new byte[BUFSIZE]; DatagramPacket receivePacket = new DatagramPacket(recbuf, BUFSIZE); // Declarar una bandera timeout boolean timeout = false; // Capturar cualquier InterruptedIOException lanzada // mientras se espera por el paquete UDP try { socket.receive (receivePacket); } catch (InterruptedIOException ioe) { timeout = true; } if (!timeout) { System.out.println ("paquete recibido!"); System.out.println ("Detalles : " + receivePacket.getAddress()); // Obtener un stream de bytes de entrada para leer el paquete UDP ByteArrayInputStream bin = new ByteArrayInputStream ( receivePacket.getData(), 0, receivePacket.getLength() ); // Conectarse a un lector para un acceso mas rapido BufferedReader reader = new BufferedReader ( 34 new InputStreamReader ( bin ) ); // Hacer un bucle indefinido for (;;) { String line = reader.readLine(); // Verificar fin de datos if (line == null) break; else System.out.println (line); } } else { System.out.println ("paquete perdido!"); } // Dormir por un segundo, para permitirle al usuario ver el paquete try { Thread.sleep(1000); } catch (InterruptedException ie) { } } } catch (IOException ioe) { System.err.println ("Socket error " + ioe); } } } 2.7.3 Ejecución del cliente y el servidor Echo Antes de que los clientes puedan enviar peticiones, el Echo Server debe estar activo. De lo contrario, los paquetes UDP serán enviados y luego ignorados, ya que no hay programa ejecutándose para leerlos. Sin embargo, el cliente no estará quieto si la respuesta no es devuelta, sino que va a enviar los paquetes de nuevo después de dos segundos de espera. Esto es importante, ya que los servidores pueden estar inactivos o los paquetes pueden perderse en la transmisión. 35 Para ejecutar el Echo Server, escriba lo siguiente: java EchoServer Para ejecutar el cliente de Echo (ya sea en la misma máquina que el servidor o una diferente), escriba lo siguiente: java EchoClient hostname donde hostname (o localhost, si se ejecuta a nivel local) es la ubicación del servicio Echo. NOTA Recuerde que en los sistemas Unix, debe tener privilegios de root para enlazar a un puerto menor a 1024. Puede cambiar el puerto de servicio a un número mayor, pero esto debe hacerse tanto en el cliente y el servidor con el fin de volver a compilar. 2.8 Información adicional sobre UDP Si bien UDP es a veces la mejor alternativa para ciertos tipos de aplicaciones, debido a sus propiedades únicas, presenta algunos retos para los desarrolladores. Sin embargo, estos retos pueden ser satisfechos mediante la estructuración de la transmisión de datos para superar las limitaciones de UDP. A continuación se examinan estas limitaciones y cómo pueden ser superadas. 2.8.1 Falta de entrega garantizada Los paquetes enviados a través de UDP pueden perderse en tránsito-cada salto adicional entre un router y otro presenta más retrasos y aumenta la probabilidad de que un paquete pueda ser descartado cuando el TTL llega a cero. Además, los paquetes UDP pueden dañarse o perderse si la conexión de red física en la que se enrutan se cae. Ya que los paquetes de Internet son transmitidos a través de una red pública, integrada por una amplia gama de infraestructuras de red, es probable que los paquetes se pierdan en algún punto de la conexión. Por supuesto, en algunas aplicaciones de la pérdida de paquetes individuales puede no tener un efecto notable. Por ejemplo, una secuencia de vídeo puede perder unos cuantos cuadros de imagen, pero siempre que la mayoría de las tramas lleguen, la pérdida es soportable. Sin embargo, si un archivo se está transfiriendo, entonces el contenido del archivo se convertirá en ilegible, y la pérdida de paquetes llega a ser inaceptable. Si la entrega garantizada es requerida, la mejor alternativa es evitar la comunicación basada en paquetes y utilizar un mecanismo de transporte más adecuado, como el Transmission Control Protocol (TCP). No obstante, si el uso de la 36 UDP es pedido, una solución es que la parte que recibe los paquetes envíe un paquete de confirmación (también conocido como ACK) de vuelta al remitente. La ausencia de un ACK indica que el paquete se ha perdido y debe ser retransmitido. NOTA Algunos sistemas de transporte enviarán de vuelta un ACK para paquetes individuales o para una amplia gama de paquetes. A pesar de que se le añade complejidad, el reconocimiento de una serie de paquetes hace un uso más eficiente del ancho de banda. Algunos sistemas también utilizan un paquete de reconocimiento negative (NAK) para indicar que un paquete específico se perdió, lo que desencadena inmediatamente la retransmisión de ese paquete. 2.8.2 Falta de secuencia de paquetes garantizada Las aplicaciones que requieren el acceso secuencial a los datos (y seamos sinceros, que equivale a la mayoría del software) deben incluir un número de secuencia en el contenido de un paquete datagrama. Si llega un paquete fuera de orden, puede ser almacenado en buffer hasta que los paquetes anteriores se han alcanzado. La secuencia añade una pequeña cantidad de complejidad, pero hace un sistema más fiable, (siempre sabes con qué paquete estás tratando). Los paquetes duplicados deben ser desechados, y los paquetes perdidos (debido a la falta de entrega garantizada) solicitados de nuevo. 2.8.3 Falta de control de flujo Algunos sistemas pueden manejar una gran cantidad de datos, mientras que otros todavía tienen el ancho de banda muy limitado. Para evitar la inundación de un sistema con más datos de los que puede manejar, la técnica de control de flujo es utilizada. El control de flujo pone un límite a la cantidad de datos enviados y ayuda a evitar que los sistemas se sobrecarguen (y el desperdicio de ancho de banda). Imagínese el control de flujo como un limitador de agua que restringe la cantidad de líquido que fluye a través de un cabezal de ducha. Hay muchas técnicas de control de flujo, que van desde la limitación del número de paquetes enviados por segundo a limitar el número de paquetes que aún no han sido confirmados. Los ajustes para los primeros son difíciles de determinar, ya que varían dependiendo del receptor. El último es probablemente la mejor opción, al limitar el número de paquetes sin confirmar, el control se coloca en manos del receptor. Si el receptor puede recibir y responder a los paquetes de forma rápida, luego más 37 paquetes serán reconocidos y más serán enviados. Si los paquetes están inundando la red, menos respuestas volverán y un acelerador se coloca en el flujo. Algunos sistemas también pueden optar por utilizar un límite de flujo variable, que puede personalizarse para tener en cuenta la cantidad de tiempo de retorno para los acuses de recibo. Dado que UDP no ofrece control directo sobre el control de flujo, para aplicaciones a gran escala puede ser adecuado limitar el número de paquetes enviados a un host (por ejemplo, n paquetes por segundo, donde n es un número adecuado para la línea de transmisión y la velocidad de la máquina del destinatario). 3. Análisis comparativo: TCP – UDP Los dos protocolos más comunes de la capa de Transporte del conjunto de protocolos TCP/IP son el Protocolo de control de transmisión (TCP) y el Protocolos de datagramas de usuario (UDP). Ambos protocolos gestionan la comunicación de múltiples aplicaciones. Las diferencias entre ellos son las funciones específicas que cada uno implementa. 3.1 Protocolo de datagramas de usuario (UDP) UDP es un protocolo simple, sin conexión, descrito en la RFC 768. Cuenta con la ventaja de proveer la entrega de datos sin utilizar muchos recursos. Las porciones de comunicación en UDP se llaman datagramas. Este protocolo de la capa de Transporte envía estos datagramas como “mejor intento”. Entre las aplicaciones que utilizan UDP se incluyen: Sistema de nombres de dominios (DNS), Streaming de vídeo, y Voz sobre IP (VoIP). 3.2 Protocolo de control de transmisión (TCP) TCP es un protocolo orientado a la conexión, descrito en la RFC 793. TCP incurre en el uso adicional de recursos para agregar funciones. Las funciones adicionales especificadas por TCP están en el mismo orden de entrega, son de entrega confiable y de control de flujo. Cada segmento de TCP posee 20 bytes de carga en el encabezado, que encapsulan los datos de la capa de Aplicación, mientras que cada segmento UDP sólo posee 8 bytes de carga. Ver la figura para obtener una comparación. Las aplicaciones que utilizan TCP son: Exploradores Web, 38 E‐mail, y Transferencia de archivos --------------TCP y UDP utilizan el mismo esquema de direccionamiento. Una dirección IP (32 número de bits, siempre se escriben como cuatro de 8 bits sin signo de número expresado como un número decimal de 3 dígitos separados por puntos, como 193.174.25.26) y un número de puerto (un número de 16 bits expresado como un número decimal sin signo) . La dirección IP es usada por el protocolo de bajo nivel (IP) para dirigir el datagrama al host correcto en la red especificada. A continuación, el número de puerto se utiliza para enviar el datagrama para el proceso de host correcto (un programa en el host). Para un determinado protocolo (TCP o UDP), un proceso único host puede existir en un momento de recibir los datos enviados a un puerto determinado. Por lo general, un puerto se dedica a un proceso. Ventajas de TCP El sistema operativo hace todo el trabajo.. Ya que es en el sistema operativo, maneja de paquetes de entrada tiene menos cambios de contexto del kernel al espacio de usuario y la espalda, todo el montaje, ACKing, control de flujo, etc se lleva a cabo por el núcleo. TCP garantiza tres cosas: que los datos lleguen, que llegue en orden y que llegue sin duplicaciones. Los routers pueden notar los paquetes TCP y los tratan de forma especial y pueden protegerlos y retransmitirlos. TCP tiene un buen rendimiento en relación con un módem o una LAN. Desventajas de tcp El sistema operativo puede tener errores, puede ser ineficiente, y hay que tratar de remediarlo, afortunadamente puede ser optimizado para fines distintos a los que se enfrentan. TCP hace muy difícil el esforzarse más, se puede establecer unas pocas opciones de socket, pero más allá de que usted tiene que tolerar el construido en el control de flujo. TCP puede tener un montón de características que no es necesario. puede desperdiciar ancho de banda, tiempo o esfuerzo en asegurar cosas que son irrelevantes para la tarea en cuestión. 39 TCP no tiene límites de los bloques, se debe crear el suyo propio. Los routers de la Internet hoy en día están fuera de la memoria. que no pueden prestar mucha atención. Las hipótesis de diseño de TCP se descomponen en este entorno. TCP tiene rendimiento relativamente pobre en un ancho de banda con pérdida, alta, conexión de alta latencia. TCP no puede ser utilizado para la difusión o transmisión de multidifusión. TCP no puede concluir sin una transmisión de todos los datos en movimiento que explícitamente no confirmados. Desventajas de la UDP No hay garantías con udp. un paquete no podrá ser entregado, o entregado en dos ocasiones, o entregados fuera de orden, no se obtiene ningún indicio de esto a menos que el programa en el otro extremo decide decir algo. TCP realmente está trabajando en el mismo entorno, se obtiene más o menos los mismos servicios de IP y UDP. Sin embargo, TCP lo compensa bastante bien, y de una manera estandarizada. UDP no tiene control de flujo. la aplicación debe de ser de los programas de usuario. Los routers son muy descuidados con UDP, nunca se retransmiten si choca, sufre la pérdida de paquetes TCP peor. Ventajas de la UDP No se restringe a un modelo basado en la conexión de comunicación, la latencia para el inicio de las aplicaciones distribuidas es mucho menor, como es la sobrecarga del sistema operativo. Todos de control de flujo, ACKing, el registro de transacciones, etc depende de los programas de usuario; una fractura de la aplicación o no se va a poner en su camino. Además, sólo es necesario implementar y utilizar las funciones que necesita. Difusión y transmisión de multidifusión están disponibles con UDP. Desventajas de TCP para la transferencia de archivos TCP permite una ventana de un máximo de 64k, y el mecanismo de ACKING significa que la pérdida de paquetes se ha detectado erróneamente. TCP servidores de transferencia han de mantener una toma de corriente separada (ya menudo hilo separado) para cada cliente. 40 El balanceo de carga es crudo y aproximados. especialmente en las redes locales que permitan colisiones, dos transferencias simultáneas de TCP tienen una tendencia a pelear unos con otros, incluso si el remitente es el mismo. Ventajas de la UDP para la transferencia de archivos Control de flujo de hasta el espacio de usuario, Windows puede ser puestos infinito artificial inexistente latencia, bien tolerado, y las velocidades máximas aplicadas sólo por el ancho de banda real, sin embargo, las velocidades reales elegido por acuerdo del emisor y el receptor. Si recibe una imagen de forma simultánea desde varios hosts es mucho más fácil con la UDP, como es el envío de uno a varios hosts, especialmente si llegan a ser parte de la misma emisión o de un grupo multicast. 4. Bibliografía Libros Java Network Programming and Distributed Computing-David Reilly * Michael Reilly Web http://www.laynetworks.com/Comparative%20analysis_TCP%20Vs%20UDP.htm http://es.kioskea.net/contents/internet/tcp.php3 http://es.kioskea.net/contents/internet/udp.php3 http://www.profesores.frc.utn.edu.ar/sistemas/ingsanchez/Redes/Archivos/dat agramaIP.asp http://redir.no-ip.org/tutorial/networking/datagrams/definition.html Springer - An Introduction to Network Programming with Java (2007)- Page 28 Addison Wesley - Advanced JAVA Networking-Page 49, 55, 78 Addison Wesley - Java Network Programming and Distributed Computing (2002)Page 89 www.dct.udn.vn/daotao/Resource/82487.pdf http://nereida.deioc.ull.es/~cleon/psd/0405/prct/p4/html/node1.html http://nereida.deioc.ull.es/~cleon/doctorado/doc05/0405/pspdf/p4.pdf http://es.wikipedia.org/wiki/Conmutaci%C3%B3n_(redes_de_comunicaci%C3%B 3n) http://csis.pace.edu/~marchese/CS865/Lectures/Liu4/sockets.htm 41 42