¿Cuál es la diferencia entre la conexión y el tiempo de espera de lectura para los sockets?

180

3 preguntas:

  1. ¿Cuál es la diferencia entre la conexión y el tiempo de espera de lectura para los sockets?

  2. ¿Qué significa el tiempo de espera de conexión establecido en "infinito"? ¿En qué situación puede permanecer en un bucle infinitivo? ¿Y qué puede provocar que el bucle infinito muera?

  3. ¿Qué significa el tiempo de espera de lectura establecido en "infinito"? ¿En qué situación puede permanecer en un bucle infinitivo? ¿Y qué puede provocar que el bucle infinito muera?

corgrath
fuente

Respuestas:

227

1) ¿Cuál es la diferencia entre la conexión y el tiempo de espera de lectura para los sockets?

El tiempo de espera de conexión es el tiempo de espera para realizar la conexión inicial; es decir, completar el protocolo de enlace de conexión TCP. El tiempo de espera de lectura es el tiempo de espera al esperar para leer los datos 1 . Específicamente, si el servidor no puede enviar un byte <timeout> segundos después del último byte, se generará un error de tiempo de espera de lectura.

2) ¿Qué significa el tiempo de espera de conexión establecido en "infinito"? ¿En qué situación puede permanecer en un bucle infinitivo? ¿Y qué puede provocar que el bucle infinito muera?

Significa que el intento de conexión puede bloquearse para siempre. No hay un bucle infinito, pero el intento de conexión puede ser desbloqueado por otro hilo que cierre el zócalo. (Una Thread.interrupt()llamada también puede hacer el truco ... no estoy seguro).

3) ¿Qué significa el tiempo de espera de lectura establecido en "infinito"? ¿En qué situación puede permanecer en un bucle infinito? ¿Qué puede provocar que termine el ciclo infinito?

Significa que una llamada a readla secuencia del socket puede bloquearse para siempre. Una vez más, no hay un bucle infinito, pero readse puede desbloquear mediante una Thread.interrupt()llamada, cerrando el socket y (por supuesto) el otro extremo enviando datos o cerrando la conexión.


1 - No es ... como pensaba un comentarista ... el tiempo de espera de cuánto tiempo puede estar abierto o inactivo un socket.

Stephen C
fuente
8

Estos son valores de tiempo de espera impuestos por JVM para el establecimiento de la conexión TCP y esperando la lectura de datos del socket.

Si el valor se establece en infinito, no esperará para siempre. Simplemente significa que JVM no tiene tiempo de espera y el sistema operativo será responsable de todos los tiempos de espera. Sin embargo, los tiempos de espera en el sistema operativo pueden ser muy largos. En alguna red lenta, he visto tiempos de espera de hasta 6 minutos.

Incluso si establece el valor de tiempo de espera para el socket, puede no funcionar si el tiempo de espera ocurre en el código nativo. Podemos reproducir el problema en Linux conectándonos a un host bloqueado por firewall o desconectando el cable en el interruptor.

El único enfoque seguro para manejar el tiempo de espera de TCP es ejecutar el código de conexión en un subproceso diferente e interrumpir el subproceso cuando tarda demasiado.

Codificador ZZ
fuente
"Si el valor se establece en infinito, no esperará para siempre". Mientras no se trate de una discusión sobre el significado de "infinito", puede suceder que esperes mucho, mucho tiempo. Tuvimos un caso aquí, donde HttpURLConnection.getResponseCode()se colgaba un para apprx. una semana hasta que reiniciamos el proceso. Obviamente no hubo tiempo de espera establecido en el lado de JVM y tampoco hubo tiempo de espera en el lado del sistema operativo Linux.
Tom Fink
El párrafo final no es correcto. Una conexión expirará después de aproximadamente un minuto como máximo. Un hilo separado es completamente innecesario. Ciertamente puede tener lecturas que se ejecutan para siempre si no hay datos. Sin embargo, el Javadoc está equivocado acerca de que el tiempo de espera de conexión predeterminado es infinito. No lo es
Marqués de Lorne
1
@comeGetSome Eso no es correcto. Puede apagar el zócalo para la entrada. Eso hará que la lectura bloqueada se encuentre con el final de la transmisión.
Marqués de Lorne
@comeGetSome: tuve que implementar esto usando un hilo que contiene una referencia a una conexión URL HTTP abierta. Cuando dicho hilo cierra la conexión, el otro hilo arroja "java.net.SocketException: Socket closed". ¡Gracias al error JDK-8075484 por hacerme hacer eso!
fmcato
@comeGetSome ¿Seguramente puedes llamar Socket.shutdownInput()sin tener tu mano en la mano? Nota: estos tiempos de espera son impuestos por TCP, no por la JVM.
Marqués de Lorne