Java - Servidor varias peticiones (Multihilo)

 
Vista:
sin imagen de perfil
Val: 23
Ha mantenido su posición en Java (en relación al último mes)
Gráfica de Java

Servidor varias peticiones (Multihilo)

Publicado por Juan (16 intervenciones) el 10/05/2018 03:44:23
Buenas noches , tengo un problema estoy intentando hacer un servidor HTTP que atienda varias peticiones simultaneamente, y he hecho el siguiente codigo pero no soy capaz de que pueda utilizar varios hilos de ejecución.

En donde se inicia la aplicacion tengo que crear el socket servidor que espera que le llegue alguna peticion, y cuando se reciba una, la aceptará y le asignará un socket cliente para enviarle la respuesta. Pero en lugar de atenderla él mismo, el hilo principal creará un nuevo hilo para que la despache por el socket cliente que le asignó. De esta forma, podrá seguir a la espera de nuevas peticiones.


He hecho el siguiente codigo, pero no soy capaz de poner lo que anteriormente he detallado.

Espero que tengan idea y me ayuden. Muchas gracias de atemano!

Adjunto las clases que tengo creadas:

Mensajes.java


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
package PaquetePrincipal;
 
/**
 *
 * @author IMCG
 */
//Mensajes que intercambia el Servidor con el Cliente según protocolo HTTP
public class Mensajes {
 public static final String lineaInicial_OK = "HTTP/1.1 200 OK";
  public static final String lineaInicial_NotFound =
          "HTTP/1.1 404 Not Found";
//  public static final String lineaInicial_BadRequest =
//          "HTTP/1.1 400 Bad Request";
 
}


Paginas.java

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
package PaquetePrincipal;
 
/**
 * ****************************************************************************
 * clase no instanciable donde se definen algunos valores finales
 *
 * @author IMCG
 */
public class Paginas {
 
  public static final String primeraCabecera =
          "Content-Type:text/html;charset=UTF-8";
  //contenido index
  public static final String html_index = "<html>"
          + "<head><title>index</title></head>"
          + "<body>"
          + "<h1>¡Enhorabuena!</h1>"
          + "<p>Tu servidor HTTP mínimo funciona correctamente</p>"
          + "</body>"
          + "</html>";
  //contenido quijote
  public static final String html_quijote = "<html>"
          + "<head><title>quijote</title></head>"
          + "<body>"
          + "<h1>Así comienza el Quijote</h1>"
          + "<p>En un lugar de la Mancha, de cuyo nombre no quiero "
          + "acordarme, no ha mucho tiempo que vivía un hidalgo de los "
          + "de lanza en astillero, adarga antigua, rocín flaco y galgo "
          + "corredor. Una olla de algo más vaca que carnero, salpicón "
          + "las más noches, duelos y quebrantos (huevos con tocino) los "
          + "sábados, lentejas los viernes, algún palomino de añadidura "
          + "los domingos, consumían las tres partes de su hacienda. El "
          + "resto della concluían sayo de velarte (traje de paño fino), "
          + "calzas de velludo (terciopelo) para las fiestas con sus "
          + "pantuflos de lo mismo, y los días de entresemana se honraba "
          + "con su vellorí (pardo de paño) de lo más fino. Tenía en su "
          + "casa una ama que pasaba de los cuarenta, y una sobrina que "
          + "no llegaba a los veinte, y un mozo de campo y plaza, que "
          + "así ensillaba el rocín como tomaba la podadera...</p>"
          + "</body>"
          + "</html>";
  //contenido noEncontrado
  public static final String html_noEncontrado = "<html>"
          + "<head><title>noEncontrado</title></head>"
          + "<body>"
          + "<h1>¡ERROR! Página no encontrada</h1>"
          + "<p>La página que solicitaste no existe en nuestro "
          + "servidor</p>"
          + "</body>"
          + "</html>";
}

ServidorHTTP.JAVA


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
package PaquetePrincipal;
 
import java.io.BufferedReader;
import java.net.Socket;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
 
/**
 * *****************************************************************************
 * Servidor HTTP que atiende peticiones de tipo 'GET' recibidas por el puerto 
 * 8066
 *
 * NOTA: para probar este código, comprueba primero de que no tienes ningún otro
 * servicio por el puerto 8066 (por ejemplo, con el comando 'netstat' si estás
 * utilizando Windows)
 *
 * @author IMCG
 */
class ServidorHTTP {
 
  /**
   * **************************************************************************
   * procedimiento principal que asigna a cada petición entrante un socket 
   * cliente, por donde se enviará la respuesta una vez procesada 
   *
   * @param args the command line arguments
   */
  public static void main(String[] args) throws IOException, Exception {
 
    //Asociamos al servidor el puerto 8066
    ServerSocket socServidor = new ServerSocket(8066);
    imprimeDisponible();
    Socket socCliente;
 
    //ante una petición entrante, procesa la petición por el socket cliente
    //por donde la recibe
    while (true) {
      //a la espera de peticiones
      socCliente = socServidor.accept();
      //atiendo un cliente
      System.out.println("Atendiendo al cliente ");
      procesaPeticion(socCliente);
      //cierra la conexión entrante
      socCliente.close();
      System.out.println("cliente atendido");
    }
  }
 
  /**
   *****************************************************************************
   * procesa la petición recibida
   *
   * @throws IOException
   */
  private static void procesaPeticion(Socket socketCliente) throws IOException {
    //variables locales
    String peticion;
    String html;
 
    //Flujo de entrada
    InputStreamReader inSR = new InputStreamReader(
            socketCliente.getInputStream());
    //espacio en memoria para la entrada de peticiones
    BufferedReader bufLeer = new BufferedReader(inSR);
 
    //objeto de java.io que entre otras características, permite escribir 
    //'línea a línea' en un flujo de salida
    PrintWriter printWriter = new PrintWriter(
            socketCliente.getOutputStream(), true);
 
    //mensaje petición cliente
    peticion = bufLeer.readLine();
 
    //para compactar la petición y facilitar así su análisis, suprimimos todos 
    //los espacios en blanco que contenga
    peticion = peticion.replaceAll(" ", "");
 
    //si realmente se trata de una petición 'GET' (que es la única que vamos a
    //implementar en nuestro Servidor)
    if (peticion.startsWith("GET")) {
      //extrae la subcadena entre 'GET' y 'HTTP/1.1'
      peticion = peticion.substring(3, peticion.lastIndexOf("HTTP"));
 
      //si corresponde a la página de inicio
      if (peticion.length() == 0 || peticion.equals("/")) {
        //sirve la página
        html = Paginas.html_index;
        printWriter.println(Mensajes.lineaInicial_OK);
        printWriter.println(Paginas.primeraCabecera);
        printWriter.println("Content-Length: " + html.length() + 1);
        printWriter.println("\n");
        printWriter.println(html);
      } //si corresponde a la página del Quijote
      else if (peticion.equals("/quijote")) {
        //sirve la página
        html = Paginas.html_quijote;
        printWriter.println(Mensajes.lineaInicial_OK);
        printWriter.println(Paginas.primeraCabecera);
        printWriter.println("Content-Length: " + html.length() + 1);
        printWriter.println("\n");
        printWriter.println(html);
      } //en cualquier otro caso
      else {
        //sirve la página
        html = Paginas.html_noEncontrado;
        printWriter.println(Mensajes.lineaInicial_NotFound);
        printWriter.println(Paginas.primeraCabecera);
        printWriter.println("Content-Length: " + html.length() + 1);
        printWriter.println("\n");
        printWriter.println(html);
      }
 
    }
  }
 
  /**
   * **************************************************************************
   * muestra un mensaje en la Salida que confirma el arranque, y da algunas
   * indicaciones posteriores
   */
  private static void imprimeDisponible() {
 
    System.out.println("El Servidor WEB se está ejecutando y permanece a la "
            + "escucha por el puerto 8066.\nEscribe en la barra de direcciones "
            + "de tu explorador preferido:\n\nhttp://localhost:8066\npara "
            + "solicitar la página de bienvenida\n\nhttp://localhost:8066/"
            + "quijote\n para solicitar una página del Quijote,\n\nhttp://"
            + "localhost:8066/q\n para simular un error");
  }
}
Valora esta pregunta
Me gusta: Está pregunta es útil y esta claraNo me gusta: Está pregunta no esta clara o no es útil
0
Responder

Servidor varias peticiones (Multihilo)

Publicado por Tom (1525 intervenciones) el 10/05/2018 08:48:47
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
sin imagen de perfil
Val: 23
Ha mantenido su posición en Java (en relación al último mes)
Gráfica de Java

Servidor varias peticiones (Multihilo)

Publicado por Juan (16 intervenciones) el 10/05/2018 15:54:52
Buenas tardes! muchas gracias por comentar,pues como comenté , tengo hecha las tres clases como puede ver en el texto, y no soy capaz de hacer lo siguiente:

En donde se inicia la aplicacion tengo que crear el socket servidor que espera que le llegue alguna peticion, y cuando se reciba una, la aceptará y le asignará un socket cliente para enviarle la respuesta. Pero en lugar de atenderla él mismo, el hilo principal creará un nuevo hilo para que la despache por el socket cliente que le asignó. De esta forma, podrá seguir a la espera de nuevas peticiones.

Si me pudiese ayudar se lo agradeceria bastante ya que llevo intentandolo durante una semana aproximadamente y no soy capaz de dar con la clave para que vaya satisfactoriamente.

Muchas gracias de antemano!
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
sin imagen de perfil
Val: 18
Ha mantenido su posición en Java (en relación al último mes)
Gráfica de Java

Servidor varias peticiones (Multihilo)

Publicado por Xibhu (19 intervenciones) el 25/05/2018 11:14:59
Buenas, así de primeras no estás utilizando en ningún momento hilos. Está todo corriendo sobre el mismo. Debes mirarte la clase "Thread" y la interfaz "Runnable" (elige una, funcionan igual) y haz pruebas a parte a modo de ejemplo.
Cuando ya le pilles el truco adapta tu código con lo aprendido. Así de primeras como introducción, en la línea 44 debes crear el hilo y pasar el código de "procesaPetición" a la clase que extienda de Thread o implemente Runnable. Y otra cosa, en la línea 46 cuando lo hagas con hilos, de cerrar el socket se tiene que encargar el hilo también.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar