Comportamiento de los sockets Java al cerrar el flujo de salida

Resuelto Lenny Markus asked hace 12 años • 2 respuestas

¿Alguien puede explicar el siguiente comportamiento en los sockets de Java?

La idea general es esta:

  1. Abra el socket, obtenga flujos de E/S.
  2. Escribir solicitud, Cerrar flujo
  3. Leer respuesta, cerrar en flujo
  4. Cerrar el enchufe.

Aquí está mi pregunta/problema.

Si uso a PrintWriterpara la salida y luego lo cierro, se cierra todo el socket y la operación de lectura posterior falla estrepitosamente.

En cambio, si uso directamente el shutdownOutput()método del socket, cierra correctamente el canal de flujo de salida, mientras mantiene vivo el socket.

¿ Por qué cerrar el PrintWriterobjeto eliminaría todo el enchufe?

Lenny Markus avatar Jan 17 '12 12:01 Lenny Markus
Aceptado

Este puede ser el aspecto que tendrá su código:

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

Ahora, echemos un vistazo a la descripción del getOutputStream()método de Socket.

getOutputStream

public OutputStream getOutputStream() throws IOException

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

Cerrar el retorno OutputStreamcerrará el socket asociado.

Devoluciones:

un flujo de salida para escribir bytes en este socket.

Lanza:

IOException: si se produce un error de E/S al crear el flujo de salida o si el socket no está conectado.

De la descripción anterior, sabemos que cerrar el retorno OutputStreamcerrará el socket asociado.

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

Alanmars avatar Jan 17 '2012 06:01 Alanmars

Probablemente se deba a que llamar al close()método de PrintWriteres rastrear la jerarquía y llamar al close()método de SocketOutputStreamtambién. Como parte del close()método para SocketOutputStreamtambién llama al close()método para Sockettambién, lo que a la larga cerraría SocketInputStreamtambién. En su lugar , al llamar a la shutdownOutput()función se envían los datos escritos previamente seguidos de la secuencia de terminación de conexión normal de TCP. Luego desactiva el flujo de salida.

aoi222 avatar Jan 17 '2012 06:01 aoi222