2012-01-17 9 views
18

Puede alguien explicar el siguiente comportamiento en los zócalos de Java:Comportamiento de tomas de Java cuando se cierra flujo de salida

La idea general es la siguiente:

  1. socket abierto, obtener E/S arroyos.
  2. petición de escritura, cerrar corriente
  3. Respuesta de lectura, Cerrar en la corriente
  4. Cerrar zócalo.

Aquí está mi pregunta/problema.

Si utilizo un PrintWriter para la salida, y luego lo cierro, cierra el socket completo, y la operación de lectura subsiguiente falla miserablemente.

En cambio, si utilizo directamente el método shutdownOutput() del socket, cierra correctamente el canal de la corriente de salida, mientras mantiene activo el socket.

¿Por qué el objeto PrintWriter se llevaría todo el zócalo?

+1

Puede ser que necesite enjuagar antes de cerrar. –

+1

¿Ha intentado enjuagar con .flush() en sus conexiones antes de cerrar su impresora para ver si el problema no ocurre? – vcetinick

Respuesta

26

Esto puede ser lo que el código tiene:

Socket socket; 
PrintWriter pw = new PrintWriter(socket.getOutputStream()); 
pw.close(); 

Ahora, vamos a echar un vistazo a la descripción del método de getOutputStream() zócalo.

getOutputStream

public OutputStream getOutputStream() throws IOException

Devuelve un flujo de salida para esta toma. Si este socket tiene un canal asociado, el flujo de salida resultante delega todas sus operaciones en el canal. Si el canal está en modo sin bloqueo, las operaciones de escritura del flujo de salida emitirán un IllegalBlockingModeException.

Al cerrar el OutputStream devuelto se cerrará el zócalo asociado.

Devuelve:

un flujo de salida para la escritura de bytes a esta toma.

Lanza:

IOException - si se produce un error de E/S cuando se crea el flujo de salida o si el conector no está conectado.

de la descripción anterior, sabemos cerrando el OutputStream devuelto cerrará el zócalo asociado.

Ahora, cuando cierre el PrintWriter, cerrará el OutputStream asociado que cerrará el socket asociado.

+4

RTFM eh? :) Supongo que eso lo explica a fondo. ¡Gracias Bloodwolf! –

+0

@ Alanmars cómo evitar tal situación. ¿Qué ocurre si quiero mantener el socket abierto incluso después de cerrar OutputStream? ¿Hay alguna manera de hacer esto? –

2

Es probablemente debido a una llamada al método de PrintWriterclose() se remontan a través de la jerarquía y de llamar al método de la SocketOutputStreamclose() también. Como parte del método close() para el SocketOutputStream, también llama al método close() para el Socket, que a su vez cerraría el SocketInputStream también. Llamar a la función shutdownOutput() en su lugar envía cualquier información escrita previamente seguida de la secuencia de terminación de conexión normal de TCP. Luego deshabilita la secuencia de salida.

Cuestiones relacionadas