Ejercicios de Programación de Servicios y Procesos en JAVA:
Hoja 3
- Monitores en Java: Synchronized.
- Semáforos.
- El problema de los filósofos.
- El problema de los lectores y los escritores.
- Calculo de dos matrices con paralelismo.
- Uso de Locks reader y writer.
- Sopa de letras con paralelismo en su resolución automática y con GUI.
Hoja 4 y 5
- Servidor de ficheros con GUI, sockets.
- Servidor de ficheros con GUI, sockets, y paralelismo.
- Servidor de ficheros con GUI, sockets, paralelismo y criptografía asimétrica.
- Servidor de ficheros con GUI, sockets, paralelismo y criptografía simétrica y asimétrica.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 |
/* Author: Alberto Gil Tesa WebSite: http://giltesa.com License: CC BY-NC-SA 3.0 http://goo.gl/CTYnN Project: 5x04 File: ServidorTransaccion.java Date: 06/03/2013 Enunciado: Modifica el ejercicio anterior para que una vez conocidas las claves públicas del otro extremo de la comunicación, el servidor mande una clave de cifrado simétrico al cliente y lo que se envía (el contenido del fichero) se haga utilizando la clave de cifrado simétrico. Seguirá siendo necesario firmar todo. Implementa una versión firmando y otra sin firma. Modificacion y recuperacion de caracteres con clave simetrica: enviar = ( CaracterOriginal + CaracterClaveSimetrica) MOD 256; Recibir = (enviar - CaracterClaveSimetrica) MOD 256; */ import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.FileReader; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.math.BigInteger; import java.net.Socket; public class ServidorHilo extends Thread { private Socket miSocketServidor; private ObjectInputStream inSocket; private ObjectOutputStream outSocket; private File directorioFicheros = new File("FicherosServidor"); private File[] misFicheros = null; private String nombreFichero; private File fichero; private Rsa rsa; private BigInteger[] yourPublicKey; private String simetricKey; // Constantes para facilitar la legibilidad del programa: private final int ENVIARLISTAFICHEROS = 1; private final int ENVIARFICHERO = 2; private final int RECOGERFICHERO = 3; private final int ELIMINARFICHERO = 4; private final int TAMBUFFER = 32; /** * @param miSocketServidor */ public ServidorHilo(Socket miSocketServidor) { this.miSocketServidor = miSocketServidor; try { // Se crean los ObjectStreams para enviar y recibir datos por el // socket: inSocket = new ObjectInputStream(miSocketServidor.getInputStream()); outSocket = new ObjectOutputStream(miSocketServidor.getOutputStream()); // Se intercambian las claves publicas RSA: rsa = new Rsa(512); yourPublicKey = (BigInteger[])inSocket.readObject(); outSocket.writeObject(rsa.getPublicKey()); // Se elige una clave simetrica para la transaccion: simetricKey = getSimetricKey(); System.out.println("SERVIDOR: " + simetricKey); // Se firma y cifra: BigInteger datos = new BigInteger(simetricKey.getBytes()); BigInteger firmado = rsa.encrypt(datos, rsa.getPrivateKey()); BigInteger cifrado = rsa.encrypt(firmado, yourPublicKey); // Se envia la clave: outSocket.writeObject(cifrado); } catch( ClassNotFoundException e ) { e.printStackTrace(); System.out.println("Error en el objeto recibido"); } catch( IOException e ) { System.out.println("ERROR SERVIDOR (Streams mal creados): " + e); } } /** * */ @Override public void run() { // Comienza el servicio: try { // Se prepara la lista de ficheros del servidor en un Array de File: if( directorioFicheros.isDirectory() ) misFicheros = directorioFicheros.listFiles(); // El servidor como primer dato espera un Integer que le indique que // hacer a continuacion. // Asi que se recoge y se comprueba que tarea hay que atender: int tareaSolicitada = inSocket.readInt(); switch( tareaSolicitada ) { case ENVIARLISTAFICHEROS: System.out.println("Lista de ficheros solicitada"); outSocket.writeObject(getNombresFicheros(misFicheros)); outSocket.flush(); break; case ENVIARFICHERO: // Se recoge el nombre del fichero que se ha solicitado: nombreFichero = (String)inSocket.readObject(); // Se comprueba que el fichero exista y se obtiene: fichero = buscaFichero(misFicheros, nombreFichero); // Si el fichero no se obtuvo se devuelve FALSE, en caso // contrario TRUE y a continuacion se envia: outSocket.writeBoolean(( fichero == null ) ? false : true); outSocket.flush(); // Se procede a enviar el fichero: if( fichero != null ) { BufferedInputStream inFichero = new BufferedInputStream(new FileInputStream(fichero)); byte[] buffer = new byte[TAMBUFFER]; int numBytesBuffer; /* * Pasos para la transmision de datos por el socket con los datos alterados con la clave simetrica: * 1. Se lee NUMBYTES del fichero * 2. Se pasa a un array del tamaño exacto. * 3. Se alteran los bytes mediante la clave simetrica * 4. Se envian los bytes alterados por el socket. * 5. Se hace un flush() del socket */ while( ( numBytesBuffer = inFichero.read(buffer) ) > 0 ) { // 2. Buffer exacto: byte[] temp = new byte[numBytesBuffer]; for( int i = 0 ; i < temp.length ; i++ ) temp[i] = buffer[i]; // 3. Se alteran los bytes: int j = 0; for( int i = 0 ; i < temp.length ; i++ ) { j = ( j < simetricKey.length() - 1 ) ? j + 1 : 0; byte letra = (byte)simetricKey.charAt(j); temp[i] = (byte)( ( temp[i] + letra ) % 256 ); } // 4 y 5 Se envia: outSocket.write(temp); } outSocket.flush(); inFichero.close(); System.out.println("Fichero enviado: \"" + fichero.getName() + "\""); } break; case RECOGERFICHERO: nombreFichero = (String)inSocket.readObject(); fichero = new File(directorioFicheros, nombreFichero); System.out.println(fichero); BufferedOutputStream outFichero = new BufferedOutputStream(new FileOutputStream(fichero)); byte[] buffer = new byte[TAMBUFFER]; int numBytesBuffer; /* * Igual que el cliente. */ while( ( numBytesBuffer = inSocket.read(buffer) ) > 0 ) { // 2. Se des-alteran los bytes: int j = 0; for( int i = 0 ; i < buffer.length ; i++ ) { j = ( j < simetricKey.length() - 1 ) ? j + 1 : 0; byte letra = (byte)simetricKey.charAt(j); buffer[i] = (byte)( ( buffer[i] - letra ) % 256 ); } // 3. Guardado outFichero.write(buffer, 0, numBytesBuffer); } outFichero.close(); System.out.println("Fichero recibido: \"" + fichero.getName() + "\""); break; case ELIMINARFICHERO: nombreFichero = (String)inSocket.readObject(); // Se recoge el nombre del fichero que se ha solicitado. fichero = buscaFichero(misFicheros, nombreFichero); // Se comprueba que el fichero exista y se obtiene: outSocket.writeObject(( fichero == null ) ? false : true); // Si el fichero no se obtuvo se devuelve FALSE, en caso contrario TRUE y a continuacion se borra: outSocket.flush(); // Se elimita el fichero solicitado: if( fichero != null ) System.out.println(fichero.delete() ? "Fichero eliminado" : "Fichero no existe"); break; default: System.out.println("La opcion \"" + tareaSolicitada + "\" no existe"); break; } } catch( ClassNotFoundException e ) { // TODO Bloque catch generado automáticamente e.printStackTrace(); } catch( IOException e ) { System.out.println("ERROR SERVIDOR: " + e); } finally { try { miSocketServidor.close(); } catch( IOException e ) { System.out.println("ERROR SERVIDOR (Socket mal cerrado): " + e); } } } /** * Metodo privado que a partir de un array de ficheros devuelve un array de * los nombres de los ficheros. * * @param misFicheros * @return */ private static String[] getNombresFicheros(File[] misFicheros) { String[] temp = new String[misFicheros.length]; int index = 0; for( File f : misFicheros ) { temp[index] = f.getName(); index++; } return temp; } /** * Metodo privado que devuelve el fichero buscado de una lista de ficheros. * * @param misFicheros * @param fichSolicitado * @return */ private static File buscaFichero(File[] misFicheros, String fichSolicitado) { for( File f : misFicheros ) if( f.getName().equals(fichSolicitado) ) return f; return null; } /** * De un fichero de texto devuelve una linea al azar. * * @return */ private String getSimetricKey() { String temp = ( (char)0 ) + ""; // Caracter ASCII null try { BufferedReader br = new BufferedReader(new FileReader(new File("LibroRSA.txt"))); // Se cuentan las lineas del fichero: int cont = 0; while( br.readLine() != null ) cont++; br.close(); // Se saca una linea al azar: int fila = (int)( Math.random() * cont ); // Se busca la linea elegida: br = new BufferedReader(new FileReader(new File("LibroRSA.txt"))); for( int i = 0 ; i < cont ; i++ ) { if( i == fila ) temp = br.readLine(); else br.readLine(); } br.close(); } catch( FileNotFoundException e ) { e.printStackTrace(); System.out.println("ERROR SERVIDOR (Falta fichero LibroRSA.txt): " + e); } catch( IOException e ) { e.printStackTrace(); System.out.println("ERROR SERVIDOR (Clave simetrica erronea): " + e); } return temp; } } |
Hola,
Muchísimas gracias por las respuestas de los ejercicios, son de mucha utilidad, me da apuro pero…publicarás las respuestas del resto de hojas?
Un saludo
Hola Marta,
Que no te de ningún apuro, publico el contenido gustosamente y si puedo ayudar pues mejor que mejor.
En cuanto a lo de las hojas, la 5 era la última así que no puedo publicar más, ¿o te refieres a algún ejercicio de las hojas que no está hecho? si es eso me temo que se quedaran sin hacer, ahora con el trabajo y mis proyectos personales no tengo apenas tiempo :/
Saludos!