Comportamiento de los sockets Java al cerrar el flujo de salida
¿Alguien puede explicar el siguiente comportamiento en los sockets de Java?
La idea general es esta:
- Abra el socket, obtenga flujos de E/S.
- Escribir solicitud, Cerrar flujo
- Leer respuesta, cerrar en flujo
- Cerrar el enchufe.
Aquí está mi pregunta/problema.
Si uso a PrintWriter
para 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 PrintWriter
objeto eliminaría todo el enchufe?
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
OutputStream
cerrará 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 OutputStream
cerrará el socket asociado.
Ahora, cuando cierre el PrintWriter
, cerrará el asociado, OutputStream
lo que cerrará el socket asociado.
Probablemente se deba a que llamar al close()
método de PrintWriter
es rastrear la jerarquía y llamar al close()
método de SocketOutputStream
también. Como parte del close()
método para SocketOutputStream
también llama al close()
método para Socket
también, lo que a la larga cerraría SocketInputStream
tambié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.