2010-08-06 22 views
20

Me pregunto qué hace java cuando llamamos close en el inputStream y outStream asociado a un socket. Cuál es la diferencia de la llamada cercana en el socket, es decir, Socket.close().¿Cuál es la diferencia entre cerrar Input/OutputStream y cerrar Socket directamente?

si simplemente cerramos la secuencia io en el socket, pero no cerramos el socket, ¿podemos volver a abrir la secuencia io en el socket nuevamente?

¡Gracias de antemano!

+0

Ver http://stackoverflow.com/questions/484925/does-closing-the-bufferedreader-printwriter-close-the-socket-connection – Istao

Respuesta

10

Debe cerrar la secuencia de salida más externa que ha creado desde el socket. Eso lo vaciará. Cerrar el socket o el flujo de entrada no hace eso, por lo que no es adecuado. Habiendo cerrado ese flujo de salida, no necesita hacer nada más.

+0

cerrando el flujo de salida == cerrando el socket. flush + fin podría no hacerse como en shutdownOutput – irreputable

+3

Eso es completamente incorrecto. Al cerrar la secuencia de salida se vacía la * secuencia * si es necesario (consulte FilterOutputStream.close()) y luego se cierra tanto con la conexión como con el socket. Cerrar el socket * o * invocando shutdownOutput * no * vacía el socket (es decir, su búfer de envío), simplemente pone en cola un FIN al final del búfer de envío del zócalo actual. Lo que sucede después de eso es asíncrono al proceso de cierre, a menos que haya establecido un tiempo de espera "prolongado" positivo. – EJP

+4

¿Estoy en una internet diferente a la tuya? Lee el javadoc. 'shutdownOutput' -" cualquier información escrita previamente será enviada seguida por la secuencia de terminación de conexión normal de TCP "' getOutputStream' - "Cerrar el OutputStream devuelto cerrará el socket asociado" 'close' - no dice nada sobre flush y FIN. – irreputable

17

De la documentación API Java para Socket:

public void close() throws IOException Cierra esta toma. Cualquier hilo actualmente bloqueado en una operación de E/S en este socket arrojará una SocketException.

Una vez que se ha cerrado un zócalo, no está disponible para su uso en red (es decir, no se puede volver a conectar o rebotar). Se necesita crear un nuevo socket.

Al cerrar este socket, también se cerrarán InputStream y OutputStream del zócalo.

Si esta toma tiene un canal asociado, entonces el canal también se cierra.

Al cerrar el InputStream del Socket se producirá el cierre del Socket. Lo mismo ocurre con el cierre del OutputStream del zócalo.

De la documentación API de Java para Socket#getInputStream()

Cerrando el InputStream regresado cerrará el conector asociado.

Compruebe la documentación de la API, está allí por algún motivo.

+0

Así que usted está diciendo InputStream.close llama a Socket.close, que a su vez llama a InputStream.close, que a su vez llama a Socket.close, que a su vez llama a InputStream.close .....? – Pacerier

+0

Un socket está cerrado cuando las transmisiones están cerradas. Si llama a InputStream.close e intenta leer desde el socket, emitirá una excepción. Socket.close cierra la entrada y salidas del zócalo, llamando cerca de las transmisiones individuales no llama a Socket.close, pero aún dará como resultado un zócalo cerrado. – Jes

+0

Ciertamente llama a Socket.close(). La regresión infinita se evita con un indicador de "cierre". – EJP

1

Esto es más como un comentario que una buena respuesta: (yo preferiría dejar un comentario a una de las respuestas anteriores, pero no tengo el representante)

La pregunta, como lo leí, es " ¿puedo cerrar una secuencia en un socket y luego abrir una secuencia en el mismo socket? "... pero la gente parece estar respondiendo a esto:" ¿cómo debo cerrar mi socket? "... lo cual no es la pregunta que se le hace .

La respuesta a la pregunta es "no". Cuando cierra la secuencia, cierra el socket.

(Entiendo por qué, en al menos un caso, alguien podría hacer esta pregunta. Cuando está transmitiendo propiedades Java sobre un socket, el receptor debe ver EOF para reconocer el final de las propiedades - para el receptor para ver EOF, el remitente tiene que cerrar el flujo/socket. PERO, si tiene un protocolo de comando/respuesta operando sobre ese socket, NO quiere cerrarlo o perderá el canal que desea enviar una respuesta en.Ver Java streaming Properties over Socket por una manera de manejar esto)

+0

Su concepto de cerrar y volver a abrir un socket y esperar que permanezca conectado no tiene sentido. – EJP

+1

@EJP No creo que su comentario sea útil o justo. El "concepto" no es mío, está implícito en el que hace la pregunta. Si lees mi respuesta con más cuidado, habrás visto que sé que no puedes cerrarla y luego volverás a abrir una toma. He reformulado mi respuesta para que sea más fácil entender mi punto. – PMorganCA

Cuestiones relacionadas