2009-10-16 15 views
5

No soy un programador de Java. Trato de evitarlo a toda costa en realidad, pero se requiere que lo use para una clase (en el sentido de la escuela). el maestro requiere que usamos socket(), BufferedReader(), PrintStream() y varias otras cosas, incluyendo el método readLine() BufferedReader() 's.Java, sockets, BufferedReader y readline colgar ... :(

Básicamente, este es el problema que estoy teniendo. la documentación indica claramente que readLine debe devolver un valor nulo al final de la secuencia de entrada, pero eso no es lo que está pasando.

Socket link  = new Socket(this.address, 80); 
BufferedReader in = new BufferedReader(new InputStreamReader(link.getInputStream())); 
PrintWriter out = new PrintWriter( new PrintWriter(  link.getOutputStream(), true)); 

out.print("GET blah blah blah"); // http request by hand 
out.flush(); // send the get please 

while((s=in.readLine()) != null) { 

    // prints the html correctly, hooray!! 
    System.out.println(s); 
} 

en lugar de terminar al final del HTML, aparece un l en blanco ine, a 0 y otra línea en blanco y luego in.readLine() se bloquea para siempre. ¿Por qué? ¿Dónde está mi nulo?

Probé out.close() para ver si tal vez Yahoo! estaba haciendo una sesión persistente http o algo así (que no creo que sería sin el encabezado que estamos dispuestos a hacerlo).

Todos los ejemplos de sockets de Java que encuentro en la red parecen indicar while loop es la forma correcta. Simplemente no sé lo suficiente Java para depurar esto.

Respuesta

8

Tu problema es la codificación del contenido "fragmentado". Esto se usa cuando la longitud del contenido solicitado desde el servidor web no se conoce en el momento en que se inicia la respuesta. Básicamente consiste en el número de bytes que se envían, seguido de CRLF, seguido de los bytes. El final de una respuesta se señala por la secuencia exacta que está viendo. El servidor web ahora está esperando su próxima solicitud (esto también se llama "solicitud de canalización").

usted tiene varias posibilidades:

  • Uso HTTP versión 1.0. Esto hará que el servidor web cierre automáticamente la conexión cuando se haya enviado una respuesta por completo.
  • Especifique el encabezado "Conexión: cerrar" al enviar su solicitud. Esto también cerrará la conexión.
  • Parse la codificación del contenido "fragmentado" de forma correcta y sencilla, trátelo como si la respuesta ya estuviera completa, de lo que se trata.
+0

Esto tiene sentido. Necesitaba verificar los encabezados. Solo voy a usar http1.0. – jettero

+0

Sí, para un ejercicio escolar es lo más sensato. – Bombe

7

¿Estás leyendo desde un socket (no lo muestras en tu código, pero eso es lo que deduzco del texto)?

Mientras el otro lado no está cerrando la conexión, Java no sabe que es al final de la entrada, por lo readLine() está esperando al otro lado para enviar más datos y no vuelve null.

+0

... leyendo desde un socket, sí. Agregué eso a la pregunta, gracias. – jettero

4

Probar GET url HTTP/1.0. El HTTP/1.0 le dice al servidor que no puede manejar más de un documento por conexión. En este caso, el servidor debe cerrar la conexión después de enviarle el resultado.

+0

Sí, eso tiene sentido y funciona.En otros idiomas simplemente cerraría mi lado del socket para que el servidor web sepa que solo va a haber una solicitud ... pero cuando salgo() parece cerrar ambos lados del enlace. ¿Hay alguna manera de cerrar exactamente un lado? ¿Estoy malinterpretando lo que sucede? – jettero

+0

Tienes razón, si llamas cerca de 'salir' también cerrarás la transmisión entrante. IIRC, eso es un error/característica en la clase de manejador de URL de Javas. –

0

Su solicitud HTTP no está completa sin 2 pares de retorno de carro + salto de línea. Probablemente también deba llamar al cerrar después de enviar la solicitud:

out.print("GET /index.html HTTP/1.0\r\n"); 
// maybe print optional headers here 
// empty line 
out.print("\r\n"); 
out.flush(); 
out.close(); 
Cuestiones relacionadas