PSP Solucionario Defweb
PSP Solucionario Defweb
UNIDAD 1.
Programación multiproceso
Actividades propuestas
80486DX2 i5-12600HX
Fecha de lanzamiento 1992 2022
Número de bits 32 64
Número de núcleos 1 12
Frecuencia 66MHz 4.6GHz
Precio lanzamiento aproximado 5000€ 1700€
actualizado
(ordenador completo)
Desde una PowerShell, ejecutar el comando kill indicando como parámetro el identificador del
proceso:
© Ediciones Paraninfo 2
Programación de servicios y procesos
En sistemas Linux, se puede obtener el PID utilizando el comando ps. El comando kill se debe
ejecutar de la misma manera que en la PowerShell de Windows.
Actividades finales
Actividades de comprobación
1.1. 1.2. 1.3. 1.4. 1.5. 1.6. 1.7. 1.8. 1.9. 1.10.
D D B C B A B C C C
Actividades de aplicación
1.11.
En cambio, el lenguaje de programación compilado debe ser traducido por medio del proceso
denominado compilación a lenguaje máquina (binario) antes de su ejecución. Por lo tanto, se
necesita disponer de un compilador (programa específico para cada sistema operativo).
Los lenguajes interpretados suelen ser más lentos que los compilados, ya que la traducción se
realiza durante el proceso de ejecución, mientras que en los compilados se realiza en la
compilación (proceso previo a la ejecución).
© Ediciones Paraninfo 3
Programación de servicios y procesos
Los lenguajes interpretados suelen ser más versátiles en cuanto a que el mismo programa se
puede ejecutar en diferentes sistemas operativos siempre y cuando se disponga del intérprete
adecuado.
1.12.
1.13.
1.14.
Una bifurcación o fork se inicia a partir de un proceso común en ejecución. Una vez creados, cada
bifurcación será en sí misma un proceso y tendrá independencia del resto.
1.15.
La base de datos intermedia hace de elemento común para la comunicación. En dicha base de
datos deberá existir una tabla en la que se almacene la información que se quiera intercambiar
compuesta por los siguientes datos:
- Emisor.
- Receptor.
- Información.
- Indicador de si ha sido leída la información.
© Ediciones Paraninfo 4
Programación de servicios y procesos
1.16.
Cada proceso escribirá la información que desee transmitir al otro proceso en un fichero distinto.
Por ejemplo, Proceso 1, escribe en Fichero 1 lo que desea transmitir a Proceso 2. Proceso 2 hará
lo propio sobre Fichero 2.
Cada cierto tiempo, los procesos irán a su fichero de recepción a buscar la información
almacenada, la leerán y la eliminarán. Alternativamente, se podría guardar la información leída
en otros ficheros distintos si desea dejar copia de la información procesada.
1.17.
1.18.
Los hilos son más ligeros que los procesos, ya que comparten recursos como la memoria. Cuando
el sistema operativo crea un proceso le debe dotar de todos los recursos necesarios para su
ejecución. En cambio los hilos se crean en el contexto de un proceso creado previamente, por lo
que los recursos asignados son comunes.
© Ediciones Paraninfo 5
Programación de servicios y procesos
1.19.
1.20.
El sistema de planificación muy sencillo consiste en aplicar una técnica conocida como “Round-
robin”. Consiste en crear una lista de procesos y asignar el mismo tiempo a cada uno de ellos de
manera secuencial y ordenada. La lista se recorrerá desde el primer al último elemento para
volver a comenzar por el primero en cada iteración. El tiempo asignado por turno debe ser
suficientemente pequeño como para que no se aprecien parones en las ejecuciones de los
procesos que no están en turno, pero suficientemente grande como para que no se destine todo
el tiempo de CPU al cambio de contexto.
1.21.
- 0. Ejecución correcta.
- 1. No se dispone de acceso a la red.
- 2. No se dispone de acceso al servidor de base de datos.
- 3. Credenciales de acceso a la base de datos incorrectas.
- 4. Ordenador de destino no accesible.
- 5. Credenciales de acceso al ordenador de destino incorrecto.
- 6. No se dispone de acceso a internet.
1.22.
package [Link].actividad_1_22;
© Ediciones Paraninfo 6
Programación de servicios y procesos
Actividades de ampliación
1.23.
1.24.
Algunos lenguajes que admiten la programación de hilos de forma nativa son Java, Python, C++ o
C#.
JavaScript admite programación fuera del hilo principal de ejecución mediante el uso de Web
Workers.
1.25.
El término “Render Farm” o granja de renderización consiste en agrupar ordenadores con el fin
de reducir los tiempos de renderizado al permitir distribuir los procesos.
Existen programas que permiten aplicar este tipo de renderizado a sistemas comerciales como
Adobe After Effects, Cinema 4D o Blender.
1.26.
El primer sistema operativo multiproceso de Microsoft fue Windows NT 3.1. Creado en 1993 para
procesadores Intel Pentium de 32 bits.
1.27.
1.28.
- Round Robin. Todos los procesos tienen asignado el mismo tiempo y la misma prioridad.
Difícil de implementar.
- SJF (Short Job First). Este algoritmo da prioridad a los procesos más cortos. Sólo válido en
entornos muy concretos, ya que puede provocar que procesos largos no tengan tiempo
asignado.
- FCFS (First-come, First-served). También conocido como FIFO. El primer proceso que llega
es el primero que se atiende. Es muy sencillo de implementar, pero muy poco eficiente.
© Ediciones Paraninfo 7
Programación de servicios y procesos
UNIDAD 2.
Programación multihilo
Actividades propuestas
2.1. Ejecución de run en lugar de start
Las cuatro primeras líneas de salida, las que indican que los ratones han comenzado a
alimentarse, se muestran inmediatamente. Las cuatro líneas finales, las que indican que los
ratones han terminado de alimentarse, van apareciendo transcurridos los segundos
correspondientes al tiempo que se les asignó para alimentarse. El tiempo total empleado es el
tiempo del ratón más lento, ya que todos comen a la vez.
Al sustituir en el código las llamadas a start() por llamadas a run(), la ejecución genera la siguiente
salida:
Cada ratón comienza a alimentarse, espera el tiempo indicado y termina de alimentarse antes de
pasar al siguiente ratón. Por lo tanto, el tiempo total empleado es la suma de los tiempos
empleados por cada ratón. Esto se debe a que la llamada a run(), pese a que no genera un error
de sintaxis, no provoca la ejecución de un hilo independiente como tal, sino una ejecución
secuencial síncrona, haciendo que cada instrucción bloquee la ejecución del único hilo existente.
El código de partida para realizar las pruebas es el siguiente. Para las sucesivas ejecuciones se
debe modificar el valor de la constante NUMERO_HILOS declarada en el método main.
© Ediciones Paraninfo 8
Programación de servicios y procesos
package [Link];
@Override
public void run() {
[Link]();
}
Tras dos ejecuciones con cada configuración de número de hilos (2, 10, 100 y 100), el resultado
obtenido se muestra en la siguiente tabla.
Se comparan, para cada número de hilos, el alimento que deberían consumir los ratones y el que
han consumido en realidad.
© Ediciones Paraninfo 9
Programación de servicios y procesos
En los resultados obtenidos se pueden observar algunas características propias de los sistemas
multihilo y de los problemas de concurrencia asociados. En primer lugar, llama la atención que las
salidas son distintas en diferentes ejecuciones. Esto se debe a que el procesador tiene diferentes
cargas de trabajo en distintas ejecuciones. Se observa como las salidas esperadas y las obtenidas
no son consistentes en todas las ejecuciones.
En el contexto de ejecución en que se realizaron las pruebas, los problemas comienzan a aparecer
a partir de 10 hilos. Esto no tiene por qué ocurrir en todas las ejecuciones, ya que depende de
múltiples factores. Sucesivas pruebas arrojarán diferentes resultados, pero en general a mayor
número de hilos más frecuentes e importantes serán las diferencias entre resultados esperados y
obtenidos.
Es importante recordar que estos errores no se van a producir siempre, por lo que podrían no
detectarse en pruebas de software tradicionales. Los errores de concurrencia deben evitarse
durante la codificación, anticipando los posibles riesgos.
package [Link];
import [Link];
@Override
public void run() {
[Link]();
}
© Ediciones Paraninfo 10
Programación de servicios y procesos
Planificador:
package [Link].actividad_propuesta_2_4;
import [Link];
import [Link];
@Override
public void run() {
try {
[Link]("Es momento de
andar durante 5 minutos");
} catch (Exception e) {
[Link]();
}
}
© Ediciones Paraninfo 11
Programación de servicios y procesos
package [Link].actividad_propuesta_2_4;
import [Link].*;
package [Link].actividad_propuesta_2_5;
En el código que forma parte del enunciado existen dos segmentos que se pueden considerar
sección crítica: la línea 16 y las líneas comprendidas entre las líneas 21 y 23.
En ambos casos, se está accediendo a una variable estática directa o indirectamente a través de
operaciones no atómicas, lo que podría generar errores de concurrencia.
© Ediciones Paraninfo 12
Programación de servicios y procesos
El problema de concurrencia se resuelve sustituyendo la clase ArrayList del paquete [Link] por
CopyOnWriteArrayList del paquete [Link].
package [Link];
import [Link];
import [Link].*;
@Override
public void run() {
while(true) {
if ([Link]()>=10) {
[Link](0);
}
else if ([Link]()<10) {
[Link](new String("Texto"));
}
for (String string : lista) {
//Recorriendo la lista
}
}
}
Se ejecutan simultáneamente un método del hilo 1 y un método del hilo 2, pero nunca dos
métodos del mismo hilo.
© Ediciones Paraninfo 13
Programación de servicios y procesos
package [Link];
Al utilizar los dos bloques sincronizados el mismo objeto de bloqueo, se impide que dichos
métodos se ejecuten concurrentemente. Por lo tanto, la ejecución se realizará método a método,
de manera secuencial.
© Ediciones Paraninfo 14
Programación de servicios y procesos
package [Link];
import [Link];
import [Link];
@Override
public void run() {
while(true) {
if ([Link]()>=10) {
synchronized(objetoBloqueo) {
[Link](0);
}
}
else if ([Link]()<10) {
synchronized(objetoBloqueo) {
[Link](new String("Texto"));
}
}
synchronized(objetoBloqueo) {
for (String string : lista) {
//Recorriendo la lista
}
}
}
}
© Ediciones Paraninfo 15
Programación de servicios y procesos
Esto se debe a que inicialmente se lanza el método 1 de todos los hilos y, dado que hay un
semáforo que impide que más de dos hilos ejecuten un mismo método, hasta que los primeros
hilos no terminen la ejecución del método 1 y pasen al método 2, no dejarán recursos para el
resto de los hilos.
package [Link];
import [Link];
@Override
public void run() {
this.metodo1();
this.metodo2();
}
© Ediciones Paraninfo 16
Programación de servicios y procesos
Actividades finales
Actividades de comprobación
2.1. 2.2. 2.3. 2.4. 2.5. 2.6. 2.7. 2.8. 2.9. 2.10. 2.11. 2.12. 2.13. 2.14.
C A B B A C C A C C B C C C
Actividades de aplicación
2.15.
En la programación secuencial, las instrucciones de los programas se ejecutan una tras otra,
independientemente de la capacidad de proceso que tenga el ordenador en el que se están
procesando y de las características de los propios programas.
En la programación concurrente, las instrucciones de los programas se intentan ejecutar de
manera simultánea, aprovechando las capacidades de computación del ordenador en el que se
están procesando.
2.16.
• Nuevo. El hilo está creado, pero no está en ejecución.
• Ejecutable. El hilo podrá estar en ejecución o pendiente de ejecución.
• Bloqueado. Está bloqueado a la espera ser liberado.
• Esperando. Está esperando a que otro hilo realice una acción concreta.
• Esperando un tiempo. Está esperando a que otro hilo realice una acción concreta durante
un tiempo determinado.
• Finalizado. El hilo ha terminado de ejecutarse.
2.17.
Algunos de los problemas de concurrencia tienen que ver con el orden de ejecución de los hilos.
Este orden viene determinado por el sistema operativo e intervienen circunstancias de contexto
que pueden ser distintas en distintas ejecuciones. Por lo tanto, en función de estas circunstancias
cambiantes, el orden podrá ser el adecuado o no. Normalmente, a mayor número de hilos y mayor
número de cálculos, mayor es la posibilidad de que se produzcan errores.
2.18.
La interfaz Runnable es aquella que deben implementar los bloques de código que se ejecuten
como un hilo independiente. La clase Thread implementa esta interfaz.
2.19.
Java es un lenguaje que solo admite herencia simple. De esta manera, si se hereda de la clase
Thread, ya no se podrá heredar de ninguna otra clase. Por ejemplo, si se desea crear una versión
multihilo de una clase existente, no se podría heredar de esta a la vez que de la clase Thread. La
interfaz Runnable sí permitiría heredar de esa clase base e implementar la funcionalidad multihilo.
2.20.
© Ediciones Paraninfo 17
Programación de servicios y procesos
El método sleep() permite suspender la ejecución del hilo desde el que se invoca. Acepta como
parámetro la cantidad de tiempo en milisegundos.
2.22.
En computación, una interrupción es una suspensión temporal de la ejecución de un proceso o de
un hilo de ejecución. Las interrupciones no suelen pertenecer a los programas, sino al sistema
operativo, viniendo generadas por peticiones realizadas por los dispositivos periféricos.
2.23.
• Utilizar atributos estáticos. Los atributos estáticos son comunes a todas las instancias, por
los que independientemente de la manera de construir los hilos la información es
compartida.
• Existen otras formas de compartir información, ya sea a través de ficheros, bases de datos
o servicios de red o de internet.
2.24.
Declarando una variable como volatile solo existirá una copia en el procesador.
2.25.
El método join permite indicar a un hilo que debe suspender su ejecución hasta que termina otro
hilo de referencia. Este método debe ejecutarse dentro del bloque asíncrono del código, ya que lo
contrario no tendrá ningún efecto.
2.26.
Los semáforos se suelen utilizar cuando un recurso tiene una capacidad limitada y se desea
controlar el número de consumidores de dicho recurso.
Actividades de ampliación
2.27.
Según la documentación del método stop() de la clase Thread, este método es intrínsecamente
inseguro. Detener un subproceso con [Link] hace que desbloquee todos los monitores que
ha bloqueado, lo que podría generar un comportamiento arbitrario.
2.28.
Un pool de hilos es una colección limitada de hilos que se pueden utilizar bajo demanda, evitando
un uso abusivo de los recursos del sistema.
© Ediciones Paraninfo 18
Programación de servicios y procesos
Las clases Executors, Executor y ExecutorService proporcionan los mecanismos para crear pools de
hilos en Java.
2.29.
Las interrupciones en los sistemas operativos son los mecanismos disponibles para que los
dispositivos periféricos (teclado, ratón, tarjeta de red, etc.) “interrumpan” temporalmente la
ejecución de los programas para enviar las señales relacionadas con los eventos que suceden en
dichos dispositivos.
2.30.
Python dispone de una clase Semaphore que dispone de los métodos acquire() y reléase() para
adquirir y liberar el semáforo.
2.31.
“CUDA son las siglas de Compute Unified Device Architecture (Arquitectura Unificada de
Dispositivos de Cómputo) que hace referencia a una plataforma de computación en paralelo que
incluye un compilador y un conjunto de herramientas de desarrollo creadas por Nvidia que
permiten a los programadores usar una variación del lenguaje de programación C (CUDA C) para
codificar algoritmos en GPU de Nvidia.
Por medio de wrappers se puede usar Python, Fortran, Julia y Java en vez de C/C++.”
Fuente: Wikipedia.
2.32.
“El problema de la cena de los filósofos o problema de los filósofos cenando (dining philosophers
problem) es un problema clásico de las ciencias de la computación propuesto por Edsger Dijkstra
en 1965 para representar el problema de la sincronización de procesos en un sistema operativo.
Cinco filósofos se sientan alrededor de una mesa y pasan su vida cenando y pensando. Cada
filósofo tiene un plato de fideos y un tenedor a la izquierda de su plato. Para comer los fideos son
necesarios dos tenedores y cada filósofo solo puede tomar los que están a su izquierda y derecha.
Si cualquier filósofo toma un tenedor y el otro está ocupado, se quedará esperando, con el tenedor
en la mano, hasta que pueda tomar el otro tenedor, para luego empezar a comer.
Si dos filósofos adyacentes intentan tomar el mismo tenedor a una vez, se produce una condición
de carrera: ambos compiten por tomar el mismo tenedor, y uno de ellos se queda sin comer.
Si todos los filósofos toman el tenedor que está a su derecha al mismo tiempo, entonces todos se
quedarán esperando eternamente, porque alguien debe liberar el tenedor que les falta. Nadie lo
hará porque todos se encuentran en la misma situación (esperando que alguno deje sus
tenedores). Entonces los filósofos se morirán de hambre. Este bloqueo mutuo se denomina
interbloqueo o deadlock.
El problema consiste en encontrar un algoritmo que permita que los filósofos nunca se mueran de
hambre.”
© Ediciones Paraninfo 19
Programación de servicios y procesos
Fuente: Wikipedia.
[Link]
© Ediciones Paraninfo 20
Programación de servicios y procesos
UNIDAD 3.
Programación de comunicaciones en red
Actividades propuestas
3.1. Lectura remota de ficheros.
Se deben crear dos proyectos, uno para alojar el programa servidor y otro para alojar el
programa cliente.
Servidor:
package [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
© Ediciones Paraninfo 21
Programación de servicios y procesos
Cliente:
package [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
© Ediciones Paraninfo 22
Programación de servicios y procesos
}
public void abrirCanalesDeTexto() {
[Link]("(Cliente) Abriendo canales de texto...");
//Canales de lectura
isr = new InputStreamReader(is);
br = new BufferedReader(isr);
//Canales de escritura
pw = new PrintWriter(os, true);
[Link]("(Cliente) Canales de texto abiertos.");
}
public void cerrarCanalesDeTexto() throws IOException {
[Link]("(Cliente) Cerrando canales de texto.");
//Canales de lectura
[Link]();
[Link]();
//Canal de escritura
[Link]();
[Link]("(Cliente) Canales de texto cerrados.");
}
public void solicitarFichero(String mensaje) {
[Link]("(Cliente) Enviando mensaje...");
[Link](mensaje);
[Link]("(Cliente) Mensaje enviado.");
}
© Ediciones Paraninfo 23
Programación de servicios y procesos
Al introducir en la ejecución del programar cliente el nombre del fichero remoto, se muestra el
contenido de este por el terminal:
Se deben crear dos proyectos, uno para alojar el programa servidor y otro para alojar el
programa cliente.
Servidor:
package [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
© Ediciones Paraninfo 24
Programación de servicios y procesos
try {
socket = new DatagramSocket(49171);
byte[] bufferLectura = new byte[32];
DatagramPacket datagramaEntrada =
new DatagramPacket(bufferLectura,
[Link]);
String mensajeRecibido;
pw = new PrintWriter(new File("G:/salida_udp.txt"));
do {
[Link](datagramaEntrada);
mensajeRecibido = new String(bufferLectura);
[Link](mensajeRecibido);
if ([Link]("FIN")) {
break;
}
[Link](mensajeRecibido);
bufferLectura = new byte[32];
datagramaEntrada =
new DatagramPacket(bufferLectura,
[Link]);
} while (true);
} catch (SocketException e) {
[Link]();
} catch (IOException e) {
[Link]();
} finally {
if (socket!=null) {
[Link]();
}
if (pw!=null) {
[Link]();
}
}
}
}
Cliente:
package [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
© Ediciones Paraninfo 25
Programación de servicios y procesos
Actividades finales
Actividades de comprobación
3.1. 3.2. 3.3. 3.4. 3.5. 3.6. 3.7. 3.8. 3.9. 3.10
D C B A A C B C A C
Actividades de aplicación
3.11.
1. Aplicación.
2. Transporte.
3. Internet.
4. Interfaz de red.
3.12.
Las direcciones IPv4 y las IPv6 tienen diferencias en el formato y la composición. Esto afecta al
número de direcciones diferentes que se pueden crear con una y otra versión, siendo en el caso de
las direcciones IPv6 extremadamente alto.
3.13.
En las comunicaciones en red, un paquete es cada uno de los elementos en los que se divide un
mensaje para optimizar su transferencia.
3.14.
Es un paquete de datos en la transferencia realizada mediante el protocolo UDP.
© Ediciones Paraninfo 26
Programación de servicios y procesos
3.15.
package [Link];
import [Link];
import [Link];
3.17.
package [Link];
import [Link];
import [Link];
3.18.
Los sockets TCP están orientados a conexión y garantizan la recepción íntegra de los paquetes. Es,
por lo tanto, un protocolo fiable; pero dicha fiabilidad supone ralentización en las transmisiones, ya
que los paquetes que se pierden o deterioran deben ser reenviados.
Los sockets UDP no están orientados a conexión y no garantizan la recepción íntegra de los
paquetes, pudiendo sufrir pérdidas. Esta potencial pérdida de fiabilidad permite que la velocidad
en la transmisión sea mayor.
3.19.
La web permite intercambiar recursos, ya sean estos documentos HTML, ficheros PDF o imágenes,
por citar algunos ejemplos. Dichos recursos deben poderse transmitir de manera íntegra o, de lo
contrario, el receptor sería incapaz de restaurar el recurso solicitado. UDP, al contrario, admite
pérdidas de paquetes, por lo que, en caso de producirse, la recuperación del recurso solicitado por
parte del cliente sería imposible en muchos casos.
3.20.
Los pasos para crear un servidor basado en sockets TCP son los siguientes:
© Ediciones Paraninfo 27
Programación de servicios y procesos
1. Crear un socket de tipo servidor (server socket) asociado a una dirección y a un puerto
concretos.
2. Indicar al socket de tipo servidor que quede a la espera de peticiones de establecimiento
de conexión por parte del cliente.
3. Aceptar el establecimiento de la conexión y obtención del socket.
7. Cerrar de la conexión.
3.21.
Los pasos para la creación de un cliente basado en sockets TCP son los siguientes:
1. Crear un socket de tipo cliente (socket) indicando la dirección IP y el puerto del servidor.
2. Abrir los flujos de lectura y escritura de datos.
Actividades de ampliación
3.24.
[Link]
Otra interesante fuente para comprender y profundizar sobre el modelo OSI es el siguiente artículo
de IONOS:
© Ediciones Paraninfo 28
Programación de servicios y procesos
[Link]
normas-y-protocolos/
3.25.
“El IPv6 es una actualización al protocolo IPv4, diseñado para resolver el problema de agotamiento
de direcciones. Su desarrollo comenzó en diciembre de 1998 cuando Steve Deering y Robert
Hinden, empleados de Cisco y Nokia publicaron una especificación formal del protocolo a través de
un RFC12 y aún continua su implementación.”
Fuente: Wikipedia.
3.26.
• Java. [Link]
• Python. [Link]
• PHP. [Link]
• C#. [Link]
• C++. [Link]
• Kotlin. [Link]
3.27.
3.28.
“La clase de socket de datagrama de multidifusión es útil para enviar y recibir paquetes de
multidifusión IP. Un MulticastSocket es un DatagramSocket (UDP), con capacidades adicionales
para unirse a "grupos" de otros hosts de multidifusión en Internet.”
3.29.
En el siguiente artículo de MDN Web Docs proporciona una explicación clara y concisa sobre el
concepto de WebSocket:
[Link]
© Ediciones Paraninfo 29
Programación de servicios y procesos
UNIDAD 4.
Generación de servicios en red
Actividades propuestas
4.1. Acceso a un servicio web que proporcione un fichero JSON, recuperarlo y mostrar el
contenido por la consola.
Para la solución de este ejercicio se utiliza el API del periódico El País para consultar los premios
obtenidos en los números de lotería del premio de Navidad.
Siendo numero el número que se desea consultar, como se puede ver en el siguiente ejemplo:
[Link]
En la solución propuesta se analiza la respuesta como una cadena de caracteres, aunque podría
procesarse como un fichero JSON utilizando la librería adecuada.
package [Link].ap_4_1;
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
.followRedirects([Link]).build();
HttpRequest request =
[Link]().GET().uri([Link](direccion))
.headers("Content-Type",
"text/plain").setHeader("User-Agent", "Mozilla/5.0").build();
HttpResponse<String> response = [Link](request,
[Link]());
© Ediciones Paraninfo 30
Programación de servicios y procesos
} catch (Exception e) {
[Link]();
}
}
}
package [Link].ap_4_2;
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
public GestorFTP() {
clienteFTP = new FTPClient();
}
© Ediciones Paraninfo 31
Programación de servicios y procesos
}
[Link](FTP.BINARY_FILE_TYPE);
}
package [Link].ap_4_3;
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
© Ediciones Paraninfo 32
Programación de servicios y procesos
Servidor:
package [Link].ap_4_4;
import [Link];
import [Link];
© Ediciones Paraninfo 33
Programación de servicios y procesos
package [Link].ap_4_4;
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
package [Link].ap_4_4;
import [Link];
import [Link];
© Ediciones Paraninfo 34
Programación de servicios y procesos
String definicion;
public Elemento(String termino, String definicion) {
[Link] = termino;
[Link] = definicion;
}
public String getTermino() {
return [Link];
}
public String getDefinicion() {
return [Link];
}
}
}
Cliente:
package [Link].ap_4_4;
import [Link];
import [Link];
package [Link].ap_4_4;
import [Link];
import [Link];
import [Link];
public Cliente() {
try {
Registry registro = [Link]("localhost",
5555);
gestorDefiniciones = (IGestorDefiniciones)
[Link]("GestorDefiniciones");
} catch (Exception e) {
[Link]();
}
}
© Ediciones Paraninfo 35
Programación de servicios y procesos
Actividades finales
Actividades de comprobación
4.1 4.2 4.3 4.4 4.5 4.6 4.7 4.8 4.9 4.10 4.11 4.12
D C A A A B C D A D C B
Actividades de aplicación
4.13.
2. 200-299. Éxito.
3. 300-399. Redirección.
4. 400-499. Error del cliente.
Ambos son protocolos para la recepción y lectura de correos. IMAP almacena los correos en el
servidor, por lo que se pueden leer desde varios dispositivos. POP3, en cambio, descarga los
correos al programa cliente y los elimina del servidor, por lo que una vez leídos en un dispositivo
no se pueden leer desde otros.
4.17.
Ambos protocolos sirven para conectarse de manera remota a un ordenador en modo texto, con el
objetivo habitual de adminístralo. En la actualidad se debe utilizar SSH, ya que es un protocolo
seguro que cifra la información transferida entre los ordenadores cliente y servidor, mientras que
Telnet no cifra la información, siendo, por lo tanto, un protocolo inseguro.
4.18.
Los pasos para realizar con esta clase una petición HTTP sin parámetros son los siguientes:
• Creación de URL.
• Apertura de la conexión.
• Configuración de la conexión:
– Método HTTP.
– Tipo de contenido.
© Ediciones Paraninfo 36
Programación de servicios y procesos
– Sistema de codificación.
– Desconexión.
4.19.
Para realizar una petición HTTP, se deben seguir los siguientes pasos:
• Crear el objeto HttpClient, indicando versión del protocolo, así como otros datos
opcionales como el comportamiento en caso de que existan redirecciones del servidor.
• Realizar la petición a través del método send del HttpClient y asignar la respuesta de la
petición a un objeto HttpResponse.
• Procesar la respuesta.
4.20.
4.21.
Utilizando las librerías de Apache y sin tener en cuenta el control de errores o de rechazos del
servidor, los pasos esenciales para descargar un fichero son los siguientes:
• Validarse con las credenciales de la cuenta del usuario en el servidor (método login).
4.22.
Los pasos que seguir para enviar correos electrónicos que solo contienen texto plano son los
siguientes:
• Creación de la sesión, indicando la URL del servidor de SMTP, el puerto, si utiliza SSL y si se
requiere autenticación.
© Ediciones Paraninfo 37
Programación de servicios y procesos
• Creación del mensaje (objeto Message). En este objeto se incluye la dirección de correo del
emisor, la del destinatario, el asunto y el texto del mensaje.
• Cierre de la conexión.
4.23.
La descarga de correos electrónicos desde Java se puede realizar siguiendo estos pasos:
• Creación de la sesión (Session) IMAP, indicando el protocolo, el nombre del host, el puerto,
si utiliza SSL y el servidor de confianza asociado.
• Apertura de la carpeta.
Actividades de ampliación
4.25.
“El servidor HTTP Apache es un servidor web HTTP de código abierto, para plataformas Unix (BSD,
GNU/Linux, etc.), Microsoft Windows, Macintosh y otras.”.
Fuente: Wikipedia.
4.26.
“Un sniffer es una herramienta de software o hardware que permite al usuario supervisar su tráfico
en Internet en tiempo real y capturar todo el tráfico de datos que entran y salen de su equipo.”.
Fuente: Avast.
El tráfico transferido mediante HTTP será legible si es interceptado por el “sniffer”. En cambio, si se
utiliza el protocolo HTTPS, el tráfico transferido podrá ser interceptado, pero no leído, ya que está
cifrado.
4.27.
• 202. Indica que la petición ha sido recibida pero que todavía no se ha actuado al respecto.
© Ediciones Paraninfo 38
Programación de servicios y procesos
• 402. Es un código de estado de respuesta no estándar que está reservado para uso futuro.
Este código de estado se creó para habilitar el efectivo digital o los sistemas de (micro)
pago e indicaría que el contenido solicitado no está disponible hasta que el cliente realice
un pago.
• 403. Indica que el servidor ha recibido y ha entendido la petición, pero rechaza enviar una
respuesta.
4.28.
• FileZilla
• FireFTP
• SmartFTP
4.29.
Pasos:
• Subir el fichero:
o put rutal-local/nombre-fichero-local
4.30.
• Desde un terminal:
o ssh nombre-usuario@nombre-servidor
o Introducir la contraseña del usuario.
4.31.
“CORBA es un estándar para distribuir objetos a través de redes de modo que las operaciones en
dichos objetos puedan llamarse de forma remota. CORBA no está asociado con ningún lenguaje de
programación en particular y cualquier lenguaje que tenga un enlace CORBA puede utilizarse para
llamar e implementar objetos CORBA. Los objetos se describen en una sintaxis denominada IDL
(Interface Definition Language)”.
Fuente: IBM.
La diferencia frente a RMI es que CORBA no está asociado a ningún lenguaje de programación,
mientras que RMI es específico de Java.
© Ediciones Paraninfo 39
Programación de servicios y procesos
UNIDAD 5.
Técnicas criptográficas para la programación
de aplicaciones seguras
Actividades propuestas
5.1. Implementa un sistema criptográfico basado en el método César.
package [Link].ap_5_1;
import [Link];
import [Link];
[Link](([Link](caracterClaro)+DESPLAZAMIENTO)%CifradorC
[Link]());
switch (caracterClaro) {
case ' ':
caracterCifrado = ' ';
break;
case '.':
caracterCifrado = '.';
© Ediciones Paraninfo 40
Programación de servicios y procesos
break;
case ',':
caracterCifrado = ',';
break;
}
[Link]((char)caracterCifrado);
}
return textoCifrado;
}
public static StringBuffer descrifrar(StringBuffer entrada) {
StringBuffer textoDescifrado = new StringBuffer();
for (int i=0;i<[Link]();i++) {
char caracterCifrado = [Link](i);
int posicion = ([Link](caracterCifrado)-
DESPLAZAMIENTO);
if (posicion<0)
posicion=[Link]()+posicion;
int caracterDescifrado =
[Link](posicion);
switch (caracterCifrado) {
case ' ':
caracterDescifrado = ' ';
break;
case '.':
caracterDescifrado = '.';
break;
case ',':
caracterDescifrado = ',';
break;
}
[Link]((char)caracterDescifrado);
}
return textoDescifrado;
}
© Ediciones Paraninfo 41
Programación de servicios y procesos
La web de Eclipse ([Link] dispone, junto con la descarga del IDE, de los
resúmenes SHA-512 para poder comprobar la integridad.
Este ejercicio se ejecuta sobre una descarga de Eclipse y su resumen SHA-512 almacenado en un
fichero de texto.
package [Link].ap_5_2;
import [Link];
import [Link];
package [Link].ap_5_2;
import [Link];
import [Link];
import [Link];
import [Link];
© Ediciones Paraninfo 42
Programación de servicios y procesos
java [Link].ap_5_3.DescifradorAESSimple
G:/[Link] mellamospiderman
java [Link].ap_5_3.DescifradorAESSimple
G:/[Link] mellamospiderman
package [Link].ap_5_3;
import [Link];
import [Link];
import [Link];
package [Link].ap_5_3;
import [Link];
import [Link];
import [Link];
© Ediciones Paraninfo 43
Programación de servicios y procesos
package [Link].ap_5_3;
import [Link];
import [Link];
import [Link];
clave_publica_emisor.key
clave_privada_emisor.key
clave_publica_receptor.key
clave_privada_receptor.key
© Ediciones Paraninfo 44
Programación de servicios y procesos
package [Link].ap_5_4;
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link].PKCS8EncodedKeySpec;
import [Link].X509EncodedKeySpec;
© Ediciones Paraninfo 45
Programación de servicios y procesos
package [Link].ap_5_4;
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
© Ediciones Paraninfo 46
Programación de servicios y procesos
}
[Link]();
[Link]();
//CIFRADO CON CLAVE PUBLICA
FileInputStream fisCifrado = new FileInputStream(new
File("G:/test/[Link]"));
FileOutputStream fosFinal = new FileOutputStream(new
File("G:/test/[Link]"));
while (([Link](bloque)) != -1) {
byte[] bloqueCifradoPublicaDestinatario = cifrar(bloque,
clavePublicaDestinatario);
[Link](bloqueCifradoPublicaDestinatario);
}
[Link]();
[Link]();
} catch (Exception e) {
[Link]();
}
}
}
package [Link].ap_5_4;
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
© Ediciones Paraninfo 47
Programación de servicios y procesos
En primer lugar, se debe ejecutar la clase ClavesManager para generar las claves pública y
privada.
package [Link].ap_5_5;
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
© Ediciones Paraninfo 48
Programación de servicios y procesos
import [Link].PKCS8EncodedKeySpec;
import [Link].X509EncodedKeySpec;
© Ediciones Paraninfo 49
Programación de servicios y procesos
package [Link].ap_5_5;
import [Link];
import [Link];
import [Link];
import [Link];
Actividades finales
Actividades de comprobación
5.1 5.2 5.3 5.4 5.5 5.6 5.7 5.8 5.9 5.10 5.11
B D B C B D D A B A B
Actividades de aplicación
5.12.
Los sistemas criptográficos son seguros en la medida en que el tiempo que se necesita para
descifrar por “fuerza bruta” el mensaje cifrado sea tanto que no resulte útil realizar este proceso.
© Ediciones Paraninfo 50
Programación de servicios y procesos
Por ejemplo, el cifrado CESAR es descifrable en décimas de segundo, mientras que en su origen era
prácticamente indescifrable. El algoritmo DES, mucho más moderno y complejo, es descifrable en
varios días. En todos los casos, a medida que los computares son más rápidos, el tiempo necesario
para romper un sistema criptográfico es menor, pudiéndolo convertir en poco seguro.
5.13.
5.14.
En un sistema de almacenamiento de credenciales utilizando resúmenes (HASH), las contraseñas se
almacenan cifradas con este tipo de algoritmos. De esta manera nunca se almacena la contraseña
en claro, evitando así su exposición si el sistema es atacado.
5.15.
La verificación se realiza de la siguiente manera: el usuario introduce su identificador de usuario y
contraseña; la contraseña se resume con un algoritmo HASH; se lee el resumen de la contraseña
previamente almacenado en una base de datos asociado al identificador del usuario; se comparan
los resúmenes HASH introducidos por el usuario y el almacenado: si ambos coinciden, el usuario
queda verificado.
5.16.
5.18.
Una colisión en un algoritmo HASH surge cuando dos mensajes distintos generan el mismo
resumen. Es muy poco probable que ocurran, pero no imposible. Pese a ello, se admiten en
algunos contextos los algoritmos en los que se ha demostrado que existen colisiones, ya que las
posibilidades de que estos se produzcan (por ejemplo, dos contraseñas que generan el mismo
resumen) son tan remotas que prácticamente es imposible.
5.19.
La firma digital permite asociar la identidad del emisor a un documento, aunque este no esté
cifrado, garantizando así el origen del mensaje.
5.20.
Cualquier transferencia de datos está sujeta a la posibilidad de que sea interceptada. Si esto
ocurre, la información obtenida de manera ilegítima debe ser ilegible (estar cifrada). Los protocolos
TCP y HTTP no cifran la información, por lo que son protocolos no seguros salvo que se tomen las
medidas oportunas.
© Ediciones Paraninfo 51
Programación de servicios y procesos
5.21.
No es infrecuente que un sistema sea atacado y obtenidos los resúmenes de las contraseñas
almacenadas en él. Si esto ocurre, los atacantes tratarán obtener contraseñas en claro que generen
los resúmenes recuperados. Para ello necesitan, fundamentalmente, tiempo. Si antes de que haya
transcurrido el tiempo necesario para obtener la contraseña en claro esta ha sido cambiada, el
riesgo de un acceso ilegítimo al sistema se minimiza.
5.22.
Un sitio web que proporciona la contraseña en claro cuando sus usuarios se la solicitan no utiliza
un algoritmo HASH para su almacenamiento. Por lo tanto, la debe almacenar en claro o cifrada con
un algoritmo reversible. En ambos casos es un riesgo muy alto que se debe evitar.
5.23.
Un mensaje cifrado con la clave privada del emisor y, posteriormente, con la clave pública del
receptor, solo puede ser descifrado con la clave privada del receptor (confidencialidad) y,
posteriormente, con la clave pública del emisor (identidad).
5.24.
Actividades de ampliación
5.25.
En este artículo de Wikipedia se hace una extensa descripción del cifrado César:
[Link]
Para descifrar un texto con este sistema hay que conocer el número de desplazamientos con el que
se cifró el texto.
El texto en claro se obtiene desplazando hacia la izquierda cada carácter del texto cifrado en el
alfabeto tantas posiciones como el número de desplazamientos. Por lo tanto, el descifrado es el
siguiente:
sp
da
pn
© Ediciones Paraninfo 52
Programación de servicios y procesos
5.26.
URL: [Link]
MD5 HASH generado: d1921aa0ca3c1146a01520c04e6caa9e
URL: [Link]
MD5 HASH generado: d1921aa0ca3c1146a01520c04e6caa9e
URL: [Link]
MD5 HASH generado: d1921aa0ca3c1146a01520c04e6caa9e
5.27.
5.28.
• [Link]
© Ediciones Paraninfo 53
Programación de servicios y procesos
5.29.
AES-CBC: En el modo CBC (cipher-block chaining), antes de ser cifrado, a cada bloque de texto se le
aplica una operación XOR con el bloque previo ya cifrado. De este modo, cada bloque cifrado
depende de todos los bloques de texto claros usados hasta ese punto. Además, para hacer cada
mensaje único se debe usar un vector de inicialización en el primer bloque.
AES-CFB: El modo CFB (cipher feedback), en su forma más simple, utiliza toda la salida del cifrado
de bloque. En esta variación, es muy similar a CBC, convierte un cifrado de bloque en un cifrado de
flujo de sincronización automática.
AES-OFB: El modo OFB (output feedback) emplea una clave para crear un bloque pseudoaleatorio
que es operado a través de XOR con el texto claro para generar el texto cifrado. Requiere de un
vector de inicialización que debe ser único para cada ejecución realizada.
Fuente: Wikipedia
5.30.
Este artículo publicado en la web de Google contiene una explicación bastante extensa y
comprensible sobre el modo en el que funciona este protocolo:
[Link]
5.31.
Fuente: IBM
5.32.
“La extensión Java Secure Socket (JSSE) permite comunicaciones seguras en Internet. Proporciona
un marco y una implementación para una versión Java de los protocolos SSL, TLS y DTLS e incluye
funcionalidad para el cifrado de datos, autenticación de servidor, integridad de mensajes y
autenticación de cliente opcional.”
Fuente: Oracle
© Ediciones Paraninfo 54