Está en la página 1de 23

Universidad Nacional Experimental de Guayana.

Área de Informática
Sistemas Distribuidos. 2017-I

Comunicación de datagramas (UDP) y de Streams (TCP)

Javier Olivero, Argel Sánchez


Javier020594@gmail.com, argelsanchez19@gmail.com
Lunes 23 Enero – Sistemas Distribuidos

Resumen

En este informe se verá cómo es el comportamiento de la comunicación mediante la


interfaz de programas de aplicación UDP y TCP, el primero proporciona una abstracción
del paso de mensajes, es decir, el proceso emisor el cual es el programa UDPClient pueda
transmitir un mensaje simple al proceso receptor que es el programa UDPServer, y observar
si hay perdida de envío o no en la transferencia y recepción de mensajes, y el programa
TCP, el cual proporciona la abstracción de un flujo (stream) de dos direcciones entre pares
de procesos. En la que la información intercambiada consiste en un stream de ítems de
datos sin límites entre mensajes.
Introducción
UDP Proporciona un nivel de transporte no fiable de datagramas, ya que apenas
añade la información necesaria para la comunicación extremo a extremo al paquete que
envía al nivel inferior. Lo utilizan aplicaciones como NFS (Network File System) y RCP
(comando para copiar ficheros entre ordenadores remotos), pero sobre todo se emplea en
tareas de control y en la transmisión de audio y vídeo a través de una red. No introduce
retardos para establecer una conexión, no mantiene estado de conexión alguno y no realiza
seguimiento de estos parámetros. Así, un servidor dedicado a una aplicación particular
puede soportar más clientes activos cuando la aplicación corre sobre UDP en lugar de sobre
TCP.
En cuanto al modelo TCP es el protocolo que proporciona un transporte fiable de
flujo de bits entre aplicaciones. Está pensado para poder enviar grandes cantidades de

1
información de forma fiable, liberando al programador de la dificultad de gestionar la
fiabilidad de la conexión (retransmisiones, pérdida de paquetes, orden en el que llegan los
paquetes, duplicados de paquetes...) que gestiona el propio protocolo.
Tanto TCP como UDP aportan características de comunicación a Internet que la
convierten en útil para los programas de aplicación, dentro de estas características se
mencionan las siguientes.
La 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 en la comunicación el mensaje pueda que no llegue a su destino. Se transmite un
datagrama, entre procesos 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
internet y a un puerto local.
De lo anterior, se recalca que si hay fallas en el envío de mensaje puede que dicho
mensaje no llegue a su destino, un servidor enlaza su sockets a un puerto del servidor, y los
clientes a cualquier puerto local libre.
Además, en cuanto al tamaño del mensaje el proceso receptor necesita especificar
una cadena de bytes de un tamaño concreto sobre la cual se almacenará el mensaje recibido.
Si el mensaje es demasiado grande para dicha cadena, será truncado a la llegada.
Por otro lado, el tamaño del mensaje en TCP la aplicación puede elegir la cantidad
de datos que quiere recibir o leer del stream. El conjunto de datos puede ser muy pequeño
o muy grande. La implementación del flujo TCP decide cuantos datos recoge antes de
transmitirlos como uno o más paquetes IP.
En cuanto a los mensajes perdidos, el protocolo TCP utiliza un esquema de acuse de
recibo de los mensajes. Como un ejemplo de un esquema simple (no utilizado por TCP), el
extremo emisor almacena un registro de cada paquete IP enviado y el extremo receptor
acusa el recibo de todos los paquetes IP que le llegan. Si el emisor no recibe dicho acuse de
recibo dentro de un intervalo de tiempo, volverá a transmitir el mensaje.
También los destinos de los mensajes se dice que un par de procesos en
comunicación establecen una conexión antes de que puedan comunicarse mediante un
stream. Una vez que se ha establecido la comunicación, los procesos simplemente leen o

2
escriben en el stream sin tener que preocuparse de las direcciones internet ni de los
números de puertos.
Por otra parte, la comunicación de flujos TCP tiene aspectos tales como la
abstracción del flujo de bytes stream que oculta, el tamaño de mensajes donde la aplicación
escoge la cantidad de datos para leer/escribir del stream, los mensajes perdidos, el cual usa
un esquema de acuse de recibo del mensaje. Hay retransmisión del mensaje si no se recibe
acuse, el control del Flujo, donde el protocolo TCP intenta ajustar las velocidades de los
procesos que leen/escriben en un stream, la duplicación y orden de los mensajes, donde
cada paquete IP se la asocia un identificador que hace posible detectar mensajes duplicados
y reordenar los que lleguen desordenados, el destino del mensaje donde los procesos
establecen una conexión antes de enviar un stream. Una vez establecido la conexión, los
procesos leen/escriben sin enviar direcciones ni puertos.

Método Experimental

En este método experimental describiremos los procedimientos que se trabajaron en


el código y los instrumentos que se utilizaron para hacer funcionar las clases y los
programas, en primera instancia tanto el código UDPClient y UDPServer se usaran para
enviar y recibir mensajes, y asignar a cada uno de ellos el tamaño del mensaje en su buffer
y verificar si hay perdida o no de mensaje.
En la clase UDPClient que se encuentra disponible en la carpeta Ejercicio1.1, Se
uso el código DatagramPacket el cual es un constructor que crea una instancia compuesta
de cadenas de bytes que almacena el mensaje, la longitud del mensaje, y la dirección de
internet y el número de puerto local del conector destino. Como se puede observar en el
siguiente código DatagramPacket request =new DatagramPacket (m, mensajes.length (),
aHost, serverPort); Proporciona otro constructor cuando se recibe un mensaje, el mensaje
recibido se coloca en un DatagramPacket junto a su longitud y la dirección Internet. El
mensaje se recupera con los métodos getData, getPort y getAddress
Además, se añadió el código String [] arreglo = args [0].split ("\\!"); para guardar
en el arreglo la cadena formateada, y el símbolo “!“para diferenciar una cadena de la otra
cuando se envía un mensaje.

3
El código System.out.println ("A enviado " + arreglo.length + " mensaje"); Para
imprimir los mensajes que ha enviado el cliente al servidor.
Se añadió el bucle for (String mensajes: arreglo) para recorrer los mensajes y
guardarlos en la variable m.
El código byte [] buffer = new byte [20]; para cambiar el tamaño al buffer del
cliente.
En el código UDPServer se manipula el tamaño del buffer de acuerdo a las pruebas
requeridas byte [] buffer = new byte [5];
El código DatagramPacket request = new DatagramPacket(buffer, buffer.length);
aSocket.receive(request); es para esperar repetidamente los mensajes de petición de los
clientes.
Este código DatagramPacket reply = new DatagramPacket (request.getData (),
request.getLength (), request.getAddress (), request.getPort ()); aSocket.send (reply);
responde a los clientes mandándole el mismo mensaje.
Se añadió el código String a = new String (reply.getData ()); System.out.println
(“Recibido:”+a); y buffer = new byte [5]; para imprimir por pantalla los mensajes que ha
recibido del cliente, además se añadió el buffer para resetearlo nuevamente para que no
quedara basura.
En segunda instancia el siguiente procedimiento para hacer que en el caso de que un
cliente no enviara un mensaje, o se perdiera la información y no llegara la petición al
servidor, se agrego a la clase UDPServer disponible en la carpeta Ejercicio1.2 el código
aSocket.setSoTimeout (9000); para que el servidor en dado caso de que no recibiera
ninguna petición dentro de un intervalo de tiempo en este caso 9 segundos enviara un
mensaje de excepción diciendo catch (IOException e) {System.out.println("El servidor
espero 9 segundos máximo y no recibió ningún mensaje!!!, en caso de que si recibiera el
mensaje antes de que pasara el intervalo de tiempo establecido para que llegara la
información mandara un mensaje diciendo System.out.println("Recibido: " + a+" antes que
pasara los 9 segundos");
En tercera instancia Para que un cliente TCP lea repetidamente varias entradas de
un usuario y escribirlos en el stream de datos del cliente se agregaron los siguientes
códigos, el Scanner sc = new Scanner (System.in); para obtener la información del usuario.

4
int j=0, esta variable inicializa el contador para ingresar la cantidad de menaje que
se desea enviar , la variable n = 0; esta variable almacenará un número
String mensaje = " "; permite leer los bytes en el valor primitivo string
System.out.print ("Ingrese la cantidad de mensaje: "); para agregar la cantidad de mensajes
a enviar.
Se agredo el código} Catch (Exception e) {System.out.println ("Por favor ingrese
solo números ") ;} para que si se ingresa un valor de otro tipo de dato diferente al tipo int
este envié un mensaje diciendo que ingrese solo números.
Además, el bucle for para recorrer y guardar y controlar en el contador la cantidad
de mensaje que se ingreso for (int i=0; i<n; i++) {j=i+1; System.out.println ("mensaje
numero"+ j + ":"); mensaje = sc.nextLine ();
La clase TCPServer disponible en la carpeta Ejercicio2.1, se abre un conector de
servidor en su puerto de servicio (7896), y escucha las peticiones de conexión, connect.
Cuando llega una petición, crea un nuevo hilo para comunicarse con el cliente. El nuevo
hilo crea un DataInputStream y un DataOutputStream para los flujos de entrada y salida de
su conector y entonces espera a leer el mensaje del cliente y lo escribe de vuelta.
Como el mensaje está compuesto por una cadena de caracteres, el cliente y el
servidor utilizan el método writeUTF de DataOutputStream para escribirlo en el stream de
salida, y el método readUTF de DataInputStream para leerlo de stream de entrada.
Cuando un proceso ha cerrado su conector, no le será posible utilizar sus streams de
entradas y salidas. El proceso al que le a enviado datos puede leerlos de su cola, pero
cualquier lectura después de que la cola esté vacía resultara en una excepción
EOFExeption. Los intentos de utilizar un conector cerrado o de escribir en un stream roto
tienen como resultado una excepción IOException.
Una vez modificado los programas para realizar las pruebas requeridas

Resultados y discusión

Como primera instancia para mandar un mensaje de un cliente en este caso llamado
UDPClient a un servidor UDPServer ambos usando buffer, se realizaron ciertas pruebas
para observar en la transferencia de mensajes si se perdía los datos.

5
En este caso se varío el número del mensaje y el tamaño del mensaje (experimente
con no-mensajes 20, 50, 100 y tamaño-mensaje 5 Kb, 20 Kb, 100 kb). Para determinar si el
servidor detecta la pérdida de mensajes enviados por el cliente.

Código Cliente (UDPClient)

En la Línea 10 se guarda en el arreglo la cadena formateada, y el símbolo “!“es para


diferenciar una cadena de la otra, en la Línea 12 se imprime cuantos mensajes se ha
enviado desde el Cliente al Servidor con arreglo.length, en la Línea 13 el ciclo for recorre
los mensajes, en la Línea 15 se guarda en la variable m los bits de prueba, en la Línea 21 el
buffer del código del Cliente lo cambie para capacidad de 20. Obsérvese la Figura 1.1

Figura 1.1 Un cliente UDP enviando un mensaje a un servidor y recogiendo su


respuesta.

Código del Servidor (UDPServer)

En la Línea 10 el buffer del Servidor lo cambie a 5, en la Línea 21 y 22 se guarda


cada mensaje y se imprime con el mensaje “Recibido”, en la Línea 23 se resetea de nuevo

6
el buffer ya que quedaba con basura al recibir el próximo mensaje. Obsérvese el código en
la Figura 1.2

Figura1.2 Un servidor UDP recibe peticiones y las devuelve al cliente de forma


repetitiva.

Prueba número 1 con el buffer del Cliente =20 y del Servidor =5

Como podemos observar en las siguientes figuras 1.3 y 1.4 vemos que tanto el
Servidor como el Cliente imprimen en pantalla el mensaje enviado con solo 5 caracteres,
esto se debe a que el buffer del servidor es menor al del cliente, entonces la primera vez que
el cliente envíe un mensaje de 20 caracteres el servidor reconocerá solo 5, porque es lo que
está definido en su buffer, como solo reconoce 5, cuando retorna el mensaje el cliente solo
recibirá 5 caracteres.

7
Figura.1.3

Figura 1.4

Prueba número 2 con el buffer del Cliente =50 y del Servidor =20

Al igual que la prueba anterior el buffer del Cliente es mayor al buffer del Servidor,
es por esto que no se imprimen los mensajes completos, ya que el buffer del Servidor tiene
definido esa cantidad. Observe la Figura 1.5 y 1.6

Figura 1.5

Figura 1.6

8
Prueba número 3 con el buffer del Cliente =100 y el buffer del Servidor =100.

En esta prueba podemos observar que tanto en el Servidor como el Cliente, el


mensaje enviado y recibido, llegaron a su destino de manera completa, esto se debe a que el
buffer de ambos (Cliente, Servidor), son iguales entonces es por ello que a información
enviada y procesada fue recibida satisfactoriamente. Observe la Figura 1.7 y 1.8

Figura 1.7

Figura 1.8

Para ver mejor cómo funciona el envío de datos, podemos probar con el buffer del
cliente =20 y del servidor =50, en este caso el Servidor recibe el mensaje completo ya que
el buffer de éste es de 50, mientras que el Cliente imprime solo los primeros 20 caracteres
del mensaje enviado, ya que su capacidad del buffer está establecida con un buffer de 20.
Obsérvese en la Figura 1.9 y 1.10

9
Figura 1.9

El Cliente envía su mensaje pero lo imprime corto (limitado a 20) ya que el buffer
tiene ese tamaño de 20.

Figura 1.10

En esta instancia se modificó el programa Cliente para leer repetidamente una


entrada del usuario, enviando esta entrada al Servidor para responder al cliente,
estableciendo un tiempo de espera (timeouts) en el socket para que el Cliente conozca
cuando el Servidor no responde.

10
En Línea 10 se agrega el código aSocket.setSoTimeout (9000), para que el servidor
espere 9 segundos dando tiempo que se envié un mensaje, en caso de que no se envié en ese
tiempo establecido el mensaje se manda un mensaje diciendo “el servidor espero 9
segundos máximo y no recibió mensaje.

En la prueba número 1 se observa que el Servidor esperó un intervalo de tiempo


para recibir el mensaje del Cliente, el cual fue de 9 segundos, pero el Cliente no envió
ningún mensaje y el Servidor envió el mensaje “el servidor espero 9 segundos máximo y no
recibió mensaje!!!”.

11
Prueba número 2: el cliente si envió el mensaje dentro de los 9 segundos y el
servidor estaba activo.

El cliente si envió su mensaje en el tiempo correspondiente.

Prueba número 3 el cliente envío mensaje sin esta el servidor activado.

12
El cliente mando 4 mensajes pero se quedó esperando respuesta por el Servidor pero
éste estaba desactivado y se cansó de esperar.

Los programas TCPClient y TCPServer que se observan en las figuras 1.11 y 1.12
se modificaron para que el cliente lea repetidamente varias entradas de usuario de una línea
y se escriban en el stream de datos del cliente. El servidor recibe el stream de datos e
imprime el resultado de cada lectura. En el código TCPServer se agrego la línea 32
System.out.println("mensaje recibido: "+ data); para imprimir los mensajes enviados por el
usuario.

13
Figura 1.11 Un servidor TCP establece una conexión para cada cliente y les reenvía la
peticiones.

En la línea 13 se imprime por pantalla la cantidad de mensaje que se desea enviar,


en caso de que se ingrese la opción como una cadena este enviará un mensaje diciendo que
ingrese solo números, y la línea 20 a la 23 recorre el for, dependiendo de la cantidad de
mensaje que se haya ingresado.

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

14
El Servidor está esperando

Se ejecuta el cliente y pide la cantidad de mensaje que se quiere enviar

El servidor recibió el primer mensaje enviado “Javier”

El cliente envía el primer mensaje

15
El servidor recibe el segundo mensaje enviado

El cliente envía el segundo mensaje y lo recibe el servidor

El servidor recibe el tercer mensaje enviado por el cliente

El cliente envía el tercer mensaje

16
Por último el Servidor recibe el cuarto y último mensaje, todos de manera
satisfactoria sin pérdida de mensajes

El cliente envía el cuarto mensaje satisfactoriamente

En caso de que se ingresa la cantidad de mensaje como una cadena, esta le envía un
mensaje diciendo que solo puede ser ingresado números.

17
Una vez realizado estos dos procesos tanto como el UDP como el TCP se puede
comparar cuál de estos dos programas funciona de manera más segura y que los mensajes
que sean enviados no tengan una perdida mayor. Teniendo como conclusión que

El protocolo UDP, es aquel protocolo que permite el envío de datos sin que
previamente se haya establecido una conexión segura entre los dos dispositivos, y no tiene
control de flujo ni confirmación de que los paquetes hayan llegado bien, ya que algunos se
pueden perder, como pudimos observar al momento de poner valores de prueba en los
buffers tanto del servidor como del cliente, se pudieron observar ciertas perdidas de
mensaje en la actividad 1.1, porque el buffer del servidor era menor al del cliente y esto
hace que hubieran perdidas de mensajes, en cambio mientras mayor sea el buffer del
servidor pues el mensaje llegaba completamente como el cliente lo envío.

Además, en la actividad 1.2 se usaba un intervalo de tiempo en el servidor en caso


de que se cansara de esperar por una petición del cliente, es por esto que el protocolo UDP
no tiene un control de flujo para que los paquetes lleguen de manera satisfactoria a su
destino.

En cuanto al protocolo TCP tiene control sobre la transmisión de sus paquetes, no


necesitas de buffer para asignarle el tamaño de envío del mensaje que se está enviando, y
esto le da mayor efectividad a la hora de transferir mensajes, por lo tanto es más seguro que
el UDP, y se necesita una conexión previa entre los dos dispositivos para su
funcionamiento, permite la confirmación y monitorización del flujo de datos. Sus puertos
son bastante seguros. Por lo tanto, es más seguro que el UDP.

18
Se utilizó el programa MultiCastPeer con los mismos datos usados en la actividad
1.1, El código se encuentra disponible en la carpeta Ejercicio2.3, para establecer las
condiciones bajo las cuales un mensaje es perdido por alguno de los miembros de un grupo
de multidifusión. En este caso el programa se modificó para enviar varios mensajes a
diferentes grupos con la finalidad de observar si se perdía los mensajes enviados, usando
los mismos buffers asignados en la actividad 1.1, en esta primera prueba con el buffer del
MulticastpeerSender = 20 y e buffer del MulticastpeerReceiver =5, pues se observa que al
igual que la actividad 1.1 hubo perdida del mensaje en los grupos porque el tamaño
asignado que tiene el MulticastpeerSender es menor al del MulticastpeerReceiver.

19
En esta segunda prueba con el buffer del MulticastpeerSender = 50 y e buffer del
MulticastpeerReceiver =20. Se perdió información al igual que la prueba anterior.

En esta tercera prueba con el buffer del MulticastpeerSender = 100 y e buffer del
MulticastpeerReceiver =100, todos los grupos recibieron los mensajes completos, sin
perdida.

20
La multidifusión IP permite que el emisor transmita un único paquete IP a un conjunto
de computadoras, que formar un grupo de multidifusión. El emisor no tiene que estar al tanto
de las identidades de los receptores individuales y del tamaño del grupo.

21
Conclusiones

La comunicación de datagramas UDP permite establecer la conexión entre un


emisor y un receptor, en este caso nos referimos al modelo cliente-servidor, en el que se
transmite un mensaje desde un proceso emisor a un proceso receptor sin acuse de recibos.
Este protocolo aporta un procedimiento para que los programas de aplicación puedan
enviar mensajes a otros programas con un mínimo de mecanismo de protocolo,
proporciona una sencilla interfaz entre la capa de red y la capa de aplicación. Sin embargo
no otorga garantías para la entrega de mensajes.

En este informe pudimos observar algunas fallas en cuanto al envió de mensajes


desde un cliente a un servidor usando UDP, en las que se pudieron observar fallas de
omisión donde los mensajes se pierden por falta de espacio en el buffer ya sea en el origen
como el destino. En este caso los experimentos realizados con el buffer del cliente =20 y
del servidor =5 como el de 50 en el buffer del cliente y 20 en el buffer del servidor se
observaron perdidas de mensaje, ya que el buffer del servidor tenía un tamaño pequeño que
el cliente y cuando el cliente enviaba la petición este se truncaba y devolvía el tamaño que
tiene por defecto, por lo que muchas veces no es tan factible utilizar este tipo de
comunicación.

En cambio, la comunicación de streams TCP tiene muchas ventajas como


establecer la conexión y dividir la información en paquetes, garantizando que no habrá
pérdida de mensaje y llegaran ordenadamente.

Por último La multidifusión IP permite que el emisor transmita un único paquete IP a


un conjunto de computadoras, que formar un grupo de multidifusión. El emisor no tiene que
estar al tanto de las identidades de los receptores individuales y del tamaño del grupo. Pero
tiene las mismas características de fallos que el UDP, que sufren fallos de omisión, es decir, no
garantiza que los mensajes enviados sean entregados a cualquier miembro del grupo.

22
Referencias

[1] DavidARedes1lt, (2015), pagina disponible en:


http://davidaredes1it.blogspot.com.es/2015/05/diferencias-udp-y-tcp.html

[2] Kenneth L. Calvert, Michael J. Donahoo, TCP/IP Sockets in Java: Practical


Guide for Programmers, Editorial Morgan Kaufmann, 2011.

[3] Redes informáticas/Protocolos TCP y UDP en el nivel de transporte (2016),


Recuperado de:
https://es.wikibooks.org/wiki/Redes_inform%C3%A1ticas/Protocolos_TCP_y_UDP_en_el
_nivel_de_transporte#Comparativa_entre_UDP_y_TCP

23

También podría gustarte