Está en la página 1de 26

Instituto Politécnico Nacional

Escuela Superior de Cómputo

Aplicaciones para comunicaciones de red

“Practica 3 - Aplicación estilo Torrent”

Grupo: 3CM16

Integrantes:
● Estefanía Manzano Malpica.

● Morales Gonzalez Pedro Antonio.

Fecha de entrega: 11 de marzo de 2023

Profesor: Moreno Cervantes Axel Ernesto


Introducción.
Un socket es una interfaz de programación de aplicaciones (API) que permite la comunicación entre
procesos en una red. Proporciona un mecanismo para que los programas de software se comuniquen
entre sí, tanto en la misma máquina como a través de una red.

Existen diferentes tipos de sockets que se utilizan para diferentes tipos de comunicación. Los dos tipos
principales son los sockets de datagramas y los sockets de flujo.

Sockets Multicast:

Los sockets multicast son una extensión de los sockets de datagramas que permiten la comunicación
uno a muchos. En lugar de enviar un mensaje a un solo destino, un socket multicast permite enviar un
mensaje a un grupo de destinos. El grupo de destinos se identifica mediante una dirección IP multicast.

Un socket multicast puede tener múltiples miembros que se unen al grupo multicast y reciben los
mensajes enviados a ese grupo. Esto es útil para aplicaciones en las que un servidor necesita enviar
información a múltiples clientes al mismo tiempo, como en aplicaciones de transmisión en vivo o juegos
en línea.

Sockets de Datagramas:

Los sockets de datagramas son sockets que utilizan el protocolo de internet User Datagram Protocol
(UDP). Proporcionan una forma de enviar y recibir mensajes independientes entre sí, conocidos como
datagramas.

Un socket de datagramas no establece una conexión antes de enviar o recibir datos. Cada mensaje
se envía como un paquete independiente, y no se garantiza la entrega o el orden de los mensajes.
Esto hace que los sockets de datagramas sean rápidos pero menos confiables en comparación con
los sockets de flujo.

Los sockets de datagramas son útiles en situaciones donde la pérdida ocasional de datos no es crítica,
como en aplicaciones de transmisión en tiempo real o aplicaciones que requieren una alta velocidad
de transferencia de datos.

Sockets de Flujo:
Los sockets de flujo utilizan el protocolo de control de transmisión (TCP) para establecer una conexión
confiable y orientada a la conexión entre dos hosts. Proporcionan una transferencia de datos
bidireccional y garantizan la entrega ordenada y confiable de los datos.

En un socket de flujo, se establece una conexión entre el cliente y el servidor antes de que se pueda
enviar o recibir datos. Una vez establecida la conexión, los datos se transmiten en secuencia y se
garantiza que llegarán en el orden correcto.

Los sockets de flujo son adecuados para aplicaciones que requieren una comunicación confiable y sin
pérdidas, como transferencias de archivos, correo electrónico o interacciones basadas en texto en
tiempo real.

En resumen, los sockets multicast permiten la comunicación uno a muchos, los sockets de
datagramas son rápidos pero menos confiables, mientras que los sockets de flujo proporcionan una
comunicación confiable y ordenada. La elección del tipo de socket depende de los requisitos
específicos de la aplicación.
Desarrollo de la practica:
En esta práctica se implementará una aplicación estilo Google Drive, que permitirá al usuario ver los
archivos que tiene en su carpeta, así como subir o descargar archivos/carpetas a su carpeta del
servidor mediante una caja de dialogo.
Para la implementación de esta practica se realizaron 3 clases en java: DropBox, Cliente y Servidor.
Clase Cliente 01:
Se construye a modo consola con el apoyo de Java Scanner, en donde el usuario esta viendo
constantemente la representación de su carpeta personal con su contenido en el servidor.
El cliente estará ejecutando tres hilos al momento
1 package practica03redes_aplicaciontorrent;
2
3 import java.net.InetAddress;
4 import java.util.ArrayList;
5 import java.util.Scanner;
6
7 /**
8 * @author kenic
9 */
10 public class Cliente0001 {
11 public static void main(String[] args) {
12 try {
13 // Obtener la dirección IP del grupo de multidifusión y el puerto
14 InetAddress grupoMulticast = InetAddress.getByName("224.0.0.1");
15 int puertoEnviarMulticast01 = 5000;
16 int puertoRecibirMulticast01 = 5001;
17
18 // Crear un objeto ClienteMulticast y ejecutarlo en un hilo
19 //Primero Necesitamos Obtener Un Arreglo De Los Servidores Actuales
20 HiloAnuncioCliente0101 cliente = new
21 HiloAnuncioCliente0101(grupoMulticast,
22 puertoEnviarMulticast01,puertoRecibirMulticast01);
23 Thread hiloCliente = new Thread(cliente);
24 hiloCliente.start();
25
26 //Tiempo para que termine de buscar y anunciar todos los servidores.
27 Thread.sleep(10000);
28
29 //Lista Donde Guardaremos Todos Los Servidores Activos.
30 ArrayList<String> servidoresActivos = new ArrayList<>();
31
32 //Guardamos Servidores Activos.
33 servidoresActivos = cliente.obtenerListaServidoresActivos();
34
35 System.out.println("Se termino De Anunciar");
36 //Imprimimos Lista
37 System.out.println(" Lista actualizada \n Los servidores activos son: " +
38 servidoresActivos);
39
40 System.out.println("\n\n");
41
42 //System.out.println(" Continuamos");
43
44 //System.out.println("\n\n\n");
45
46 HiloBusquedaCliente0101 busqueda = new
47 HiloBusquedaCliente0101(servidoresActivos);
48 Thread hilobusqueda = new Thread(busqueda);
49 hilobusqueda.start();
50
51
52 //Tiempo para que termine de buscar y anunciar todos los servidores.
53 Thread.sleep(20000);
54
55 //Guardara la lista de las IP de los servidores que tienen el archivo
56 buscado.
57 ArrayList<String> listaServidoresTienenArchivoBuscado = new
58 ArrayList<>();
59 listaServidoresTienenArchivoBuscado =
60 busqueda.obtenerListaServidoresConArchivo();
61
62 //Guardara el nombre del Archivo que busco el cliente
63 String nombreBuscado = busqueda.NombreBuscado();
64
65 System.out.println("El nombre del archivo buscado es: " + nombreBuscado);
66 System.out.println("Los Servidores que tienen el Archivo Son Los
67 Siguiente:");
68
69 for (String elemento : listaServidoresTienenArchivoBuscado) {
70 System.out.println(elemento);
71 }
72
73 //Validamos que la lista no este vacia
74 if(listaServidoresTienenArchivoBuscado.isEmpty()){
75 //La lista esta vacia
76 System.out.println("Lo sentimos ningún servidor contiene el archivo
77 que busca");
78 }else{
79 //Preguntamos si desea Descargar el Archivo
80 System.out.println("¿Desea Descargar el archivo?");
81 System.out.println("1) Si deseo Descargar");
82 System.out.println("2) No deseo Descargar");
83 System.out.println("Ingrese el numero de la opción de su
84 preferencia");
85 String opcionDeseaDescarga;
86 Scanner opcionDescargaDeseo = new Scanner(System.in);
87 opcionDeseaDescarga = opcionDescargaDeseo.nextLine();
88 if(opcionDeseaDescarga.equalsIgnoreCase("2")){
89 System.out.println("Muchas Gracias Por utilizar el programa");
90 }else{
91 System.out.println("¿De Cual Servidor desea Descargar el
92 archivo?");
93 int k=1;
94 for (String elemento : listaServidoresTienenArchivoBuscado) {
95 System.out.println(k+") "+elemento);
96 k++;
97 }
98 System.out.println("Ingrese el numero de la opción de su
99 preferencia");
100 String opcionIPDescarga;//Guardara el numero de la IP del
101 Usuario.
102 String opcionIPDescargaFinal = "";// Guardara la ip elegida por
103 el usuario.
104 Scanner opcionDescargaIP = new Scanner(System.in);
105 opcionIPDescarga = opcionDescargaIP.nextLine();
106
107 int numero = Integer.parseInt(opcionIPDescarga);
108 k=1;
109 for (String elemento : listaServidoresTienenArchivoBuscado) {
110 if(k==numero){
111 opcionIPDescargaFinal = elemento;
112 }
113 k++;
114 }

System.out.println("Se Descargara la opción "+ opcionIPDescarga +


" De La IP " + opcionIPDescargaFinal);

HiloDescargaCliente0101 descarga = new


HiloDescargaCliente0101(opcionIPDescargaFinal,nombreBuscado);
Thread hiloDescarga = new Thread(descarga);
hiloDescarga.start();

}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
Clase Servidor:
Es la clase encargada de mandar la información de los archivos que se encuentran dentro de el
indicando al cliente si se encuentra o no el archivo solicitado, así como a su vez estar retransmitiendo
al cliente cada cierto tiempo que se encuentra activo.
1
package practica03redes_aplicaciontorrent;
2
3
import java.net.InetAddress;
4
5
/**
6
* @author kenic
7
*/
8
public class Servidor0101 {
9
public static void main(String[] args) {
10
try {
11
// Obtener la dirección IP del grupo de multidifusión y el puerto
12
InetAddress grupoMulticast = InetAddress.getByName("224.0.0.1");
13
int puertoRecibirMulticast01 = 5000;
14
int puertoEnviarMulticast01 = 5001;
15
16
// Crear un objeto ServidorMulticast y ejecutarlo en un hilo
17
18 HiloAnuncioServidor0101 servidor = new
19 HiloAnuncioServidor0101(grupoMulticast,
20 puertoRecibirMulticast01,puertoEnviarMulticast01);
21 Thread hiloServidor = new Thread(servidor);
22 hiloServidor.start();
23
24 //Tiempo para que termine de buscar y anunciar todos los servidores.
25 Thread.sleep(20000);
26
27 // Crear un objeto ServidorMulticast y ejecutarlo en un hilo
28 HiloBusquedaServidor0101 servidor02 = new HiloBusquedaServidor0101();
29 Thread hiloBusqueda = new Thread(servidor02);
30 hiloBusqueda.start();
31
32 //Tiempo para que termine de buscar y anunciar todos los servidores.
33 Thread.sleep(20000);
34
35 String nombreArchivo = servidor02.ObtenerNombreArchivoDescargar();
36
37 HiloDescargaServidor0101 descarga = new
38 HiloDescargaServidor0101(nombreArchivo);
39 Thread hiloDescarga = new Thread(descarga);
40 hiloDescarga.start();
41
42 } catch (Exception e) {
e.printStackTrace();
}
}
}

Cabe resaltar que se tienen varios servidores sin embargo lo único que cambiara de un servidor a otro
será la ip de este mismo que de forma practica y por tiempo se estableció de forma fija en cada uno
esto con la intención de que el cliente conozca cuales son los servidores activos.
Clase Anuncio Cliente
Se utiliza para que el cliente reciba cada cierto tiempo confirmación de los servidores activos, lo mismo
sucede con un hilo similar para el caso del servidor para retransmitir los servidores activos.
1 package practica03redes_aplicaciontorrent;
2
3 import java.net.DatagramPacket;
4 import java.net.InetAddress;
5 import java.net.MulticastSocket;
6 import java.net.SocketTimeoutException;
7 import java.util.ArrayList;
8
9 /**
10 * @author kenic
11 */
12 public class HiloAnuncioCliente0101 implements Runnable{
13 private InetAddress grupoMulticast;
14 private int puertoEnviarMulticast01;
15 private int puertoRecibirMulticast01;
16 private int puertoRecibirServidor01=5002;
17 private int puertoRecibirServidor02=5003;
18 private int puertoRecibirServidor03=5004;
19 private int puertoRecibirServidor04=5005;
20 private int cantidadServidoresActivos=0;
21 private ArrayList<String> servidoresActivos = new ArrayList<>();
22
23 //Constructor
24 public HiloAnuncioCliente0101(InetAddress grupo, int puertoEnviado, int
25 puertoRecibido) {
26 this.grupoMulticast = grupo;
27 this.puertoEnviarMulticast01 = puertoEnviado; //Enviado a Servidor
28 this.puertoRecibirMulticast01 = puertoRecibido; // Recibido de Servidor
29 }
30
31 //Validamos Si la IP si no se encuentra dentro de el arreglo Servidores Activos.
32 public void ValidarServidoresActivos(String direccionIP){
33 //Si no hay un elemento Actual Entonces Agrega
34 boolean validarIP = false;
35 if(servidoresActivos.isEmpty()){
36 servidoresActivos.add(direccionIP);
37 }else{
38 // Recorremos la lista uno por uno los elementos
39 for (String elemento : servidoresActivos) {
40 //Validamos si la IP ya esta agregada
41 if(elemento.equalsIgnoreCase(direccionIP)){
42 validarIP = true;
43 }
44 }
45 if(!validarIP){
46 servidoresActivos.add(direccionIP);
47 }
48 }
49 }
50
51 //Mostrar Servidores Activos en el ArrayList
52 public void MostrarServidoresActivos(){
53 // Imprimimos la lista nuevamente
54 System.out.println("Lista actualizada: " + servidoresActivos);
55 }
56
57 //Retornamos ArrayList con la lista de todos los servidores Activos.
58 public ArrayList<String> obtenerListaServidoresActivos() {
59 return servidoresActivos;
60 }
61
62
63 public void run() {
64 try {
65 // Crear un socket de multidifusión Envio
66 MulticastSocket socketEnviar = new
67 MulticastSocket(puertoEnviarMulticast01);
68 socketEnviar.joinGroup(grupoMulticast);
69
70 //Servidor01 Multicast
71 MulticastSocket socketRecibirServidor01 = new
72 MulticastSocket(puertoRecibirServidor01);
73 socketRecibirServidor01.joinGroup(grupoMulticast);
74 //Establecemos limite
75 socketRecibirServidor01.setSoTimeout(1000);
76
77 //Servidor02 Multicast
78 MulticastSocket socketRecibirServidor02 = new
79 MulticastSocket(puertoRecibirServidor02);
80 socketRecibirServidor02.joinGroup(grupoMulticast);
81 //Establecemos limite
82 socketRecibirServidor02.setSoTimeout(1500);
83
84
85 //Servidor03 Multicast
86 MulticastSocket socketRecibirServidor03 = new
87 MulticastSocket(puertoRecibirServidor03);
88 socketRecibirServidor03.joinGroup(grupoMulticast);
89 //Establecemos limite
90 socketRecibirServidor03.setSoTimeout(2000);
91
92
93 //Servidor04 Multicast
94 MulticastSocket socketRecibirServidor04 = new
95 MulticastSocket(puertoRecibirServidor04);
96 socketRecibirServidor04.joinGroup(grupoMulticast);
97 //Establecemos limite
98 socketRecibirServidor04.setSoTimeout(2500);
99
100 //Mandamos información para inicializar cuales servidores estan
101 conectados.
102 String opcion = "1";
103
104 // Convertir el mensaje en bytes
105 byte[] bufferEnviarMulticast01 = new byte[1024]; //Envia datos al
106 Servidor
107 byte[] bufferRecibirMulticast01 = new byte[1024]; // Recibe Datos del
108 Servidor
109
110 bufferEnviarMulticast01 = opcion.getBytes(); //Convertimos a bytes el
111 mensaje
112
113 if(opcion.equalsIgnoreCase("1")){
114 //Enviamos la opción
115
116 // Crear un paquete con los datos que se enviarán y la dirección del
117 grupo de multidifusión
118 DatagramPacket paqueteEnviarMulticast01 = new
119 DatagramPacket(bufferEnviarMulticast01, bufferEnviarMulticast01.length,
120 grupoMulticast, puertoEnviarMulticast01);
121
122 // Enviar el paquete a través del socket de multidifusión
123 socketEnviar.send(paqueteEnviarMulticast01);
124
125 System.out.println("Espere en lo que terminamos de anunciar La
126 Conexión");
127 //Recibimos Respuesta
128
129 try{
130 // Crear un paquete para recibir datos Servidor 01
131 DatagramPacket paqueteRecibirMulticast01 = new
132 DatagramPacket(bufferRecibirMulticast01, bufferRecibirMulticast01.length);
133
134 // Recibir el paquete
135 socketRecibirServidor01.receive(paqueteRecibirMulticast01);
136
137 // Convertir los datos recibidos en un mensaje de texto
138 String mensaje = new String(paqueteRecibirMulticast01.getData(),
139 0, paqueteRecibirMulticast01.getLength());
140
141 System.out.println("La dirección IP recibida es: " + mensaje);
142
143 //Validamos que ya tengamos la IP
144 ValidarServidoresActivos(mensaje);
145
146
147 // Crear un paquete para recibir datos Servidor 02
148 DatagramPacket paqueteRecibirMulticast02 = new
149 DatagramPacket(bufferRecibirMulticast01, bufferRecibirMulticast01.length);
150
151 // Recibir el paquete
152 socketRecibirServidor02.receive(paqueteRecibirMulticast02);
153
154 // Convertir los datos recibidos en un mensaje de texto
155 String mensaje02 = new
156 String(paqueteRecibirMulticast02.getData(), 0,
157 paqueteRecibirMulticast02.getLength());
158
159 System.out.println("La dirección IP recibida es: " + mensaje02);
160
161 //Validamos que ya tengamos la IP
162 ValidarServidoresActivos(mensaje02);
163
164
165 // Crear un paquete para recibir datos Servidor 03
166 DatagramPacket paqueteRecibirMulticast03 = new
167 DatagramPacket(bufferRecibirMulticast01, bufferRecibirMulticast01.length);
168
169 // Recibir el paquete
170 socketRecibirServidor03.receive(paqueteRecibirMulticast03);
171
172 // Convertir los datos recibidos en un mensaje de texto
173 String mensaje03 = new
174 String(paqueteRecibirMulticast03.getData(), 0,
175 paqueteRecibirMulticast03.getLength());
176
177 System.out.println("La dirección IP recibida es: " + mensaje03);
178
179 //Validamos que ya tengamos la IP
180 ValidarServidoresActivos(mensaje03);
181
182
183
184 // Crear un paquete para recibir datos Servidor 04
185 DatagramPacket paqueteRecibirMulticast04 = new
186 DatagramPacket(bufferRecibirMulticast01, bufferRecibirMulticast01.length);
187
188 // Recibir el paquete
189 socketRecibirServidor04.receive(paqueteRecibirMulticast04);
190
191 // Convertir los datos recibidos en un mensaje de texto
192 String mensaje04 = new
193 String(paqueteRecibirMulticast04.getData(), 0,
194 paqueteRecibirMulticast04.getLength());
195
196 System.out.println("La dirección IP recibida es: " + mensaje04);
197
198 //Validamos que ya tengamos la IP
199 ValidarServidoresActivos(mensaje04);
200
201 System.out.println("Espere un poco Buscando Servidores
202 Activos...");
203
204
205 //Mostramos Lista con los servidores activos.
206 //MostrarServidoresActivos();
207
208
209 }catch (SocketTimeoutException e) {
210 // Se alcanzó el tiempo límite de espera y no se recibió ningún
211 datagrama
212 //System.out.println("No se recibió ningún datagrama después de
213 10 segundos");
214
215 try{
216 //Validamos los otros 3 Servidores que faltan
217 // Crear un paquete para recibir datos Servidor 02
218 DatagramPacket paqueteRecibirMulticast02 = new
219 DatagramPacket(bufferRecibirMulticast01, bufferRecibirMulticast01.length);
220
221 // Recibir el paquete
222 socketRecibirServidor02.receive(paqueteRecibirMulticast02);
223
224 // Convertir los datos recibidos en un mensaje de texto
225 String mensaje02 = new
226 String(paqueteRecibirMulticast02.getData(), 0,
227 paqueteRecibirMulticast02.getLength());
228
229 System.out.println("La dirección IP recibida es: " + mensaje02);
230
231 //Validamos que ya tengamos la IP
232 ValidarServidoresActivos(mensaje02);
233
234
235 // Crear un paquete para recibir datos Servidor 03
236 DatagramPacket paqueteRecibirMulticast03 = new
237 DatagramPacket(bufferRecibirMulticast01, bufferRecibirMulticast01.length);
238
239 // Recibir el paquete
240 socketRecibirServidor03.receive(paqueteRecibirMulticast03);
241
242 // Convertir los datos recibidos en un mensaje de texto
243 String mensaje03 = new
244 String(paqueteRecibirMulticast03.getData(), 0,
245 paqueteRecibirMulticast03.getLength());
246
247 System.out.println("La dirección IP recibida es: " + mensaje03);
248
249 //Validamos que ya tengamos la IP
250 ValidarServidoresActivos(mensaje03);
251
252 // Crear un paquete para recibir datos Servidor 04
253 DatagramPacket paqueteRecibirMulticast04 = new
254 DatagramPacket(bufferRecibirMulticast01, bufferRecibirMulticast01.length);
255
256 // Recibir el paquete
257 socketRecibirServidor04.receive(paqueteRecibirMulticast04);
258
259 // Convertir los datos recibidos en un mensaje de texto
260 String mensaje04 = new
261 String(paqueteRecibirMulticast04.getData(), 0,
262 paqueteRecibirMulticast04.getLength());
263
264 System.out.println("La dirección IP recibida es: " + mensaje04);
265
266 //Validamos que ya tengamos la IP
267 ValidarServidoresActivos(mensaje04);
268
269 System.out.println("Espere un poco Buscando Servidores
270 Activos...");
271
272 //Mostramos Lista con los servidores activos.
273 //MostrarServidoresActivos();
274
275 }catch (SocketTimeoutException i) {
276
277 try{
278 //Validamos los otros 2 Servidores que faltan
279 // Crear un paquete para recibir datos Servidor 03
280 DatagramPacket paqueteRecibirMulticast03 = new
281 DatagramPacket(bufferRecibirMulticast01, bufferRecibirMulticast01.length);
282
283 // Recibir el paquete
284 socketRecibirServidor03.receive(paqueteRecibirMulticast03);
285
286 // Convertir los datos recibidos en un mensaje de texto
287 String mensaje03 = new
288 String(paqueteRecibirMulticast03.getData(), 0,
289 paqueteRecibirMulticast03.getLength());
290
291 System.out.println("La dirección IP recibida es: " + mensaje03);
292
293 //Validamos que ya tengamos la IP
294 ValidarServidoresActivos(mensaje03);
295
296
297 // Crear un paquete para recibir datos Servidor 04
298 DatagramPacket paqueteRecibirMulticast04 = new
299 DatagramPacket(bufferRecibirMulticast01, bufferRecibirMulticast01.length);
300
301 // Recibir el paquete
302 socketRecibirServidor04.receive(paqueteRecibirMulticast04);
303
304 // Convertir los datos recibidos en un mensaje de texto
305 String mensaje04 = new
306 String(paqueteRecibirMulticast04.getData(), 0,
307 paqueteRecibirMulticast04.getLength());
308
309 System.out.println("La dirección IP recibida es: " + mensaje04);
310
311 //Validamos que ya tengamos la IP
312 ValidarServidoresActivos(mensaje04);
313
314 System.out.println("Espere un poco Buscando Servidores
315 Activos...");
316
317
318
319 //Mostramos Lista con los servidores activos.
320 //MostrarServidoresActivos();
321
322
323
324 }catch (SocketTimeoutException o) {
325
326 try{
327 //Validamos el ultimo Servidor que falta
328 // Crear un paquete para recibir datos Servidor 04
329 DatagramPacket paqueteRecibirMulticast04 = new
330 DatagramPacket(bufferRecibirMulticast01, bufferRecibirMulticast01.length);

// Recibir el paquete
socketRecibirServidor04.receive(paqueteRecibirMulticast04);

// Convertir los datos recibidos en un mensaje de texto


String mensaje04 = new
String(paqueteRecibirMulticast04.getData(), 0,
paqueteRecibirMulticast04.getLength());

System.out.println("La dirección IP recibida es: " + mensaje04);

//Validamos que ya tengamos la IP


ValidarServidoresActivos(mensaje04);

System.out.println("Espere un poco Buscando Servidores


Activos...");

//Mostramos Lista con los servidores activos.


//MostrarServidoresActivos();

}catch (SocketTimeoutException u) {
System.out.println("Espere un poco Buscando Servidores
Activos...");

//Mostramos Lista con los servidores activos.


//MostrarServidoresActivos();
}

}
}
}

}else{
// Crear un paquete con los datos que se enviarán y la dirección del
grupo de multidifusión
DatagramPacket paqueteEnviarMulticast01 = new
DatagramPacket(bufferEnviarMulticast01, bufferEnviarMulticast01.length,
grupoMulticast, puertoEnviarMulticast01);

// Enviar el paquete a través del socket de multidifusión


socketEnviar.send(paqueteEnviarMulticast01);
}

} catch (Exception e) {
e.printStackTrace();
}
}
}
Clase búsqueda Cliente
Se utiliza para que el cliente envíe por sockets datagramas el nombre del archivo que esta buscando
a los servidores activos y estos a su vez tendrán una clase similar que recibirá de igual manera la
información solicitada por el cliente del archivo que anda buscando el mismo cliente valga la
redundancia.
package practica03redes_aplicaciontorrent;

import java.net.DatagramPacket;

import java.net.DatagramSocket;

import java.net.InetAddress;

import java.net.MulticastSocket;

import java.util.ArrayList;

import java.util.Scanner;

/**

* @author kenic

*/

public class HiloBusquedaCliente0101 implements Runnable{

private InetAddress grupoMulticast;

private int puertoEnviarDatagrama01=6000;

private int puertoRecibirDatagrama01=7000;

private int puertoRecibirServidor01=6002;

private int puertoRecibirServidor02=6003;

private int puertoRecibirServidor03=6004;

private int puertoRecibirServidor04=6005;

private int puertoRecibirServidor05=6002;

private ArrayList<String> direccionesDatagrama;

private String message; //Nos guardara el nombre del archivo buscado.

//Guardamos el nombre del archivo que se desea buscar

private String busquedaArchivo;

//Guardara las direcciones de los servidores que tiene el archivo encontrado

private ArrayList<String> direccionesServidoresTienenArchivo;

//Constructor

public HiloBusquedaCliente0101(ArrayList<String> direccionesDatagrama) {


this.direccionesDatagrama = direccionesDatagrama;

public void run() {

System.out.println("Las Direcciones en el Array Son: " + direccionesDatagrama);

try {

//Recorremos la lista y Vemos cada una de las direcciones IP.

// Recorremos la lista y mostramos los elementos

//Guardamos el nombre del archivo que se desea buscar

Scanner archivoABuscar = new Scanner(System.in);

System.out.println("Ingrese por favor el nombre del archivo a buscar:");

busquedaArchivo = archivoABuscar.nextLine();

//Ayuda a saber en cual servidor Estamos.

int j =1;

//Instanciamos el array

direccionesServidoresTienenArchivo = new ArrayList<>();

for (String elemento : direccionesDatagrama) {

System.out.println("La dirección IP es: "+ elemento);

// Se crea un objeto InetAddress con la dirección IP del servidor

InetAddress addressServidor = InetAddress.getByName(elemento);

//System.out.println("La dirección IP Idress es: "+ addressServidor.getHostName() +


"\n");

//Validamos que en cual servidor estamos.

switch(elemento){

case "127.0.0.5" -> //Asignamos Puerto Del Servidor 01 que tiene esta IP
{

puertoEnviarDatagrama01 = 6001;

puertoRecibirDatagrama01 = 7001;

case "127.0.0.7" -> //Asignamos Puerto Del Servidor 02 que tiene esta IP

puertoEnviarDatagrama01 = 6002;

puertoRecibirDatagrama01 = 7002;

case "127.0.0.9" -> //Asignamos Puerto Del Servidor 02 que tiene esta IP

puertoEnviarDatagrama01 = 6003;

puertoRecibirDatagrama01 = 7003;

case "127.0.0.8" -> //Asignamos Puerto Del Servidor 02 que tiene esta IP

puertoEnviarDatagrama01 = 6004;

puertoRecibirDatagrama01 = 7004;

//System.out.println("El puerto Envio es: "+ puertoEnviarDatagrama01 + "\n");

//System.out.println("El puerto Recibo es: "+ puertoRecibirDatagrama01 + "\n");

// Se crea un objeto DatagramSocket para enviar paquetes

DatagramSocket socket = new DatagramSocket();

//Declaramos arreglo de bytes donde se mandara la información

byte[] enviarBusqueda = new byte[1024];

//Guardamos la busqueda que se debera realizar

enviarBusqueda = busquedaArchivo.getBytes();

// Se crea un objeto DatagramPacket con los datos del mensaje

// y la dirección IP y el puerto del servidor

DatagramPacket packet = new DatagramPacket(enviarBusqueda, enviarBusqueda.length,


addressServidor, puertoEnviarDatagrama01);
// Se envía el paquete al servidor

socket.send(packet);

System.out.println("Se envio Exitosamente la Busqueda");

System.out.println("IP: " + elemento);

//Recibimos Respuesta Del Servidor Si Se Encuentra o no el archivo

// Se crea un objeto DatagramSocket para recibir paquetes en el puerto 5000

DatagramSocket recibimosBusqueda = new DatagramSocket(puertoRecibirDatagrama01);

// Se crea un buffer para almacenar los datos del paquete recibido

byte[] respuestaRecibida = new byte[1024];

// Se crea un objeto DatagramPacket para recibir el paquete

DatagramPacket recibimosBusquedaPaquete = new DatagramPacket(respuestaRecibida,


respuestaRecibida.length);

// Se recibe el paquete enviado por el cliente

recibimosBusqueda.receive(recibimosBusquedaPaquete);

//Obtenemos Mensaje

message = new String(recibimosBusquedaPaquete.getData(), 0,


recibimosBusquedaPaquete.getLength());

if(message.equalsIgnoreCase("Encontrado")){

System.out.println("Archivo encontrado en el Servidor 0" + j + ": " + message);

direccionesServidoresTienenArchivo.add(elemento);

}else{

System.out.println("Archivo no encontrado en el Servidor 0" + j + ": " +


message);

System.out.println("Archivo Buscado:" + message);

j++;
System.out.println("\n\n");

System.out.println("Espere un momento por favor ...");

} catch (Exception e) {

e.printStackTrace();

//Retornamos el nombre del archivo buscado

public String NombreBuscado(){

return busquedaArchivo;

//Retornamos ArrayList con la lista de todas la IP de los servidores que tienen el archivo
buscado.

public ArrayList<String> obtenerListaServidoresConArchivo() {

return direccionesServidoresTienenArchivo;

}
Clase Descarga Cliente
Se utiliza para que el cliente le permita descargar del servidor que elija que hayan encontrado el archivo
del nombre proporcionado por el cliente, así a su vez estará del lado del servidor una clase que tenga
un hilo similar que en caso de ser seleccionado por el cliente este servidor que se seleccionó
únicamente sea el quien envíe el archivo permitiendo así al cliente poderlo descargar del servidor
elegido valga la redundancia.
package practica03redes_aplicaciontorrent;

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

/**
* @author kenic
*/
public class HiloDescargaCliente0101 implements Runnable{
private String direccionIP;
private String nombreArchivo;
private int puertoDescarga;
private String rutaServidor="";
private String rutaArchivo="";
public HiloDescargaCliente0101(String direccionIP, String nombreArchivo){
this.direccionIP = direccionIP;
this.nombreArchivo = nombreArchivo;
switch(this.direccionIP){
case "127.0.0.5" -> //Asignamos Puerto Del Servidor 01 que tiene esta
IP
{
puertoDescarga = 8001;
rutaServidor= "C:\\Users\\kenic\\OneDrive\\Onedrive
Kenichi\\Documentos\\NetBeansProjects\\Practica03Redes_AplicacionTorrent\\Servidor01\\";
rutaArchivo = rutaServidor+this.nombreArchivo;
}
case "127.0.0.7" -> //Asignamos Puerto Del Servidor 02 que tiene esta
IP
{
puertoDescarga = 8002;
rutaServidor= "C:\\Users\\kenic\\OneDrive\\Onedrive
Kenichi\\Documentos\\NetBeansProjects\\Practica03Redes_AplicacionTorrent\\Servidor02\\";
rutaArchivo = rutaServidor+this.nombreArchivo;
}
case "127.0.0.9" -> //Asignamos Puerto Del Servidor 02 que tiene esta
IP
{
puertoDescarga = 8003;
rutaServidor= "C:\\Users\\kenic\\OneDrive\\Onedrive
Kenichi\\Documentos\\NetBeansProjects\\Practica03Redes_AplicacionTorrent\\Servidor03\\";
rutaArchivo = rutaServidor+this.nombreArchivo;
}
case "127.0.0.8" -> //Asignamos Puerto Del Servidor 02 que tiene esta
IP
{
puertoDescarga = 8004;
rutaServidor= "C:\\Users\\kenic\\OneDrive\\Onedrive
Kenichi\\Documentos\\NetBeansProjects\\Practica03Redes_AplicacionTorrent\\Servidor04\\";
rutaArchivo = rutaServidor+this.nombreArchivo;
}
}
}

public void run() {


System.out.println("Al fin podremos Descargar");
System.out.println("IP: " + direccionIP);
System.out.println("Puerto: " + puertoDescarga);
System.out.println("Ruta: " + rutaArchivo);

try {
// Creamos un Socket para conectarnos al servidor en el puerto 12345
Socket socket = new Socket(direccionIP, puertoDescarga);

byte[] buffer = new byte[1024];


// Obtenemos el InputStream del socket para recibir datos del servidor
InputStream is = socket.getInputStream();

// Creamos un FileOutputStream para escribir el archivo recibido


rutaServidor= "C:\\Users\\kenic\\OneDrive\\Onedrive
Kenichi\\Documentos\\NetBeansProjects\\Practica03Redes_AplicacionTorrent\\Cliente01\\";
rutaArchivo = rutaServidor+this.nombreArchivo;
FileOutputStream fos = new FileOutputStream(rutaArchivo);
BufferedOutputStream bos = new BufferedOutputStream(fos);

int bytesRead;
// Leemos los datos recibidos en bloques de 1024 bytes y los escribimos en el
archivo de destino
while ((bytesRead = is.read(buffer)) != -1) {
bos.write(buffer, 0, bytesRead);
}

bos.flush();
socket.close();

System.out.println("Archivo descargado correctamente.");


} catch (IOException e) {
e.printStackTrace();
}
}
}
Funcionamiento:

Figura 1: Cliente

Figura 2: Servidor
Figura 3: Búsqueda Cliente
Figura 4: Búsqueda Servidor

Figura 5: Descarga del lado Cliente


Figura 6: Carpeta del lado Servidor
Conclusiones:
Pedro Antonio Morales Gonzalez:
Los sockets multicast, los sockets de datagramas y los sockets de flujo son herramientas
fundamentales en la programación de redes. Cada uno de ellos tiene sus propias características y se
utiliza en diferentes situaciones. Los sockets multicast son ideales cuando se necesita enviar datos a
múltiples destinos al mismo tiempo, como en aplicaciones de transmisión en vivo. Los sockets de
datagramas son rápidos pero menos confiables, lo que los hace adecuados para aplicaciones en
tiempo real donde la pérdida ocasional de datos no es crítica. Por otro lado, los sockets de flujo
proporcionan una comunicación confiable y ordenada, siendo ideales para transferencias de archivos
o interacciones en tiempo real que requieren una entrega segura y secuencial de los datos.

Estefania Manzano Malpica


Los sockets multicast, sockets de datagramas y sockets de flujo ofrecen distintas soluciones para la
comunicación en red. Los sockets multicast permiten la comunicación uno a muchos, lo que es
especialmente útil en aplicaciones de transmisión de datos a múltiples destinos simultáneamente. Por
otro lado, los sockets de datagramas son rápidos y eficientes en términos de velocidad, pero no
garantizan la entrega ordenada o confiable de los datos. Los sockets de flujo, por su parte, ofrecen
una comunicación confiable y orientada a la conexión, asegurando que los datos se entreguen en el
orden correcto. La elección del tipo de socket dependerá de los requisitos específicos de cada
aplicación, considerando aspectos como la velocidad, la confiabilidad y la naturaleza de la
comunicación necesaria.

También podría gustarte