2012-05-28 12 views
22

estoy creando actualmente un pequeño servidor HTTP que devuelve una página estática <p>Hello!</p> ... me trataron con tomas con Java:Un servidor Http simple con Java/Socket?

public static void main(String[] args) throws Exception { 

     // création de la socket 
     int port = 1989; 
     ServerSocket serverSocket = new ServerSocket(port); 
     System.err.println("Serveur lancé sur le port : " + port); 

     // repeatedly wait for connections, and process 
     while (true) { 

      // on reste bloqué sur l'attente d'une demande client 
      Socket clientSocket = serverSocket.accept(); 
      System.err.println("Nouveau client connecté"); 

      // on ouvre un flux de converation 

      BufferedReader in = new BufferedReader(
          new InputStreamReader(clientSocket.getInputStream()) 
         ); 
      PrintWriter out = new PrintWriter(
         new BufferedWriter(
          new OutputStreamWriter(clientSocket.getOutputStream())), 
         true); 

      // chaque fois qu'une donnée est lue sur le réseau on la renvoi sur le flux d'écriture. 
      // la donnée lue est donc retournée exactement au même client. 
      String s; 
      while ((s = in.readLine()) != null) { 
       System.out.println(s); 


     out.write("HTTP/1.0 200 OK\r\n"); 
     out.write("Date: Fri, 31 Dec 1999 23:59:59 GMT\r\n"); 
     out.write("Server: Apache/0.8.4\r\n"); 
     out.write("Content-Type: text/html\r\n"); 
     out.write("Content-Length: 59\r\n"); 
     out.write("Expires: Sat, 01 Jan 2000 00:59:59 GMT\r\n"); 
     out.write("Last-modified: Fri, 09 Aug 1996 14:21:40 GMT\r\n"); 
     out.write("\r\n"); 
     out.write("<TITLE>Exemple</TITLE>"); 
     out.write("<P>Ceci est une page d'exemple.</P>"); 
    } 

      // on ferme les flux. 
      System.err.println("Connexion avec le client terminée"); 
      out.close(); 
      in.close(); 
      clientSocket.close(); 
     } 
    } 

este código no contiene ningún error y me dieron una respuesta desde el navegador como esto:

GET/HTTP/1.1 
Host: localhost:1989 
Connection: keep-alive 
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.5 (KHTML, like Gecko) Chrome/19.0.1084.46 Safari/536.5 Comodo_Dragon/19.0.3.0 
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 
Accept-Encoding: gzip,deflate,sdch 
Accept-Language: fr-FR,fr;q=0.8,en-US;q=0.6,en;q=0.4 
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3 

¿Pero mi problema es que no consigo ninguna página en el navegador? ¿Alguna ayuda, por favor?

PS: Yo ya leí este artículo: http://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol, (lo siento por el idioma francés ...)

Respuesta

29

Además de \ r \ n después de cada línea de encabezado de solicitud, debe enviar una línea vacía después del encabezado. Ejemplo:

out.write("HTTP/1.0 200 OK\r\n"); 
// Header... 
out.write("Last-modified: Fri, 09 Aug 1996 14:21:40 GMT\r\n"); 
out.write("\r\n"); // The content starts afters this empty line 
out.write("<TITLE>Hello!</TITLE>"); 
// Content... 

corregí su código para que funcione (pero todavía no es perfecto, usted debe manejar todas las peticiones en un hilo independiente, por ejemplo, con java.util.concurrent.ThreadPoolExecutor):

public static void main(String[] args) throws Exception { 
    // création de la socket 
    int port = 1989; 
    ServerSocket serverSocket = new ServerSocket(port); 
    System.err.println("Serveur lancé sur le port : " + port); 

    // repeatedly wait for connections, and process 
    while (true) { 
     // on reste bloqué sur l'attente d'une demande client 
     Socket clientSocket = serverSocket.accept(); 
     System.err.println("Nouveau client connecté"); 

     // on ouvre un flux de converation 

     BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream())); 
     BufferedWriter out = new BufferedWriter(new OutputStreamWriter(clientSocket.getOutputStream())); 

     // chaque fois qu'une donnée est lue sur le réseau on la renvoi sur 
     // le flux d'écriture. 
     // la donnée lue est donc retournée exactement au même client. 
     String s; 
     while ((s = in.readLine()) != null) { 
      System.out.println(s); 
      if (s.isEmpty()) { 
       break; 
      } 
     } 

     out.write("HTTP/1.0 200 OK\r\n"); 
     out.write("Date: Fri, 31 Dec 1999 23:59:59 GMT\r\n"); 
     out.write("Server: Apache/0.8.4\r\n"); 
     out.write("Content-Type: text/html\r\n"); 
     out.write("Content-Length: 59\r\n"); 
     out.write("Expires: Sat, 01 Jan 2000 00:59:59 GMT\r\n"); 
     out.write("Last-modified: Fri, 09 Aug 1996 14:21:40 GMT\r\n"); 
     out.write("\r\n"); 
     out.write("<TITLE>Exemple</TITLE>"); 
     out.write("<P>Ceci est une page d'exemple.</P>"); 

     // on ferme les flux. 
     System.err.println("Connexion avec le client terminée"); 
     out.close(); 
     in.close(); 
     clientSocket.close(); 
    } 
} 
+1

Intenté esto pero todavía no está funcionando ... (ver mi actualización). –

+0

Se ha leído el encabezado de su solicitud mientras el bucle es incorrecto. Agregaré un ejemplo de trabajo a mi respuesta. –

+0

Joel olvidó enjuagar el outputtream en su ejemplo. Si prueba esta porción de código con mucho HTML, no funciona correctamente. –

1

qué máquina está usando? ¿Qué sistema operativo? Si está ejecutando una máquina UNIX, println no funcionará porque solo envía un carácter LF. HTTP requiere CR y LF para sus encabezados. Intente agregar \ r al final de sus cadenas y vea si eso funciona.

Ah, también, a su:

out.println("HTTP/1.0 200 OK"+ 
"Date: Fri, 31 Dec 1999 23:59:59 GMT"+ 
"Server: Apache/0.8.4"+ 
"Content-Type: text/html"+ 
"Content-Length: 59"+ 
"Expires: Sat, 01 Jan 2000 00:59:59 GMT"+ 
"Last-modified: Fri, 09 Aug 1996 14:21:40 GMT"+ 

Se impresión de una sola cadena, de largo.

Cambie los valores a una lista de impresión para cada cadena, o agregue \ r \ n a la cadena.

+0

¡Gracias!, Tengo Windows7, probé esto pero todavía no funciona .... –

+0

=> out.flush(); –

1

Necesita los separadores de línea correctos (\r\n) entre cada salida de línea. No es suficiente concatenarlos, lo cual puede ver si imprime la respuesta.

+0

Necesita \ r \ n. Esto es HTTP. – EJP

4

Esta es una respuesta a su última pregunta solamente y la razón de que no haya nada visible en el navegador se debe a que calculó incorrectamente el número de caracteres.

Debe ser 57 en lugar de 59.

Mejor aún es que el número de caracteres calculados de forma automática, pero creo que su muestra es sólo una muestra.

+1

Oh, bueno, eso funcionó para mí. Debería estar en la parte superior :) –