Qual é a diferença entre conexão e tempo limite de leitura para soquetes?

180

3 perguntas:

  1. Qual é a diferença entre conexão e tempo limite de leitura para soquetes?

  2. O que significa o tempo limite da conexão definido como "infinito"? Em que situação ele pode permanecer em um loop infinitivo? e o que pode provocar que o loop infinito morra?

  3. O que significa o tempo limite de leitura definido como "infinito"? Em que situação ele pode permanecer em um loop infinitivo? e o que pode provocar que o loop infinito morra?

corgrath
fonte

Respostas:

227

1) Qual a diferença entre conexão e tempo limite de leitura para soquetes?

O tempo limite da conexão é o tempo limite para fazer a conexão inicial; isto é, concluir o handshake da conexão TCP. O tempo limite de leitura é o tempo limite de espera para ler os dados 1 . Especificamente, se o servidor falhar ao enviar um byte <timeout> segundos após o último byte, um erro de tempo limite de leitura será gerado.

2) O que o tempo limite da conexão definido como "infinito" significa? Em que situação ele pode permanecer em um loop infinitivo? e o que pode provocar que o loop infinito morra?

Isso significa que a tentativa de conexão pode potencialmente bloquear para sempre. Não há loop infinito, mas a tentativa de conexão pode ser desbloqueada por outro thread que fecha o soquete. (Uma Thread.interrupt()chamada também pode fazer o truque ... não tenho certeza.)

3) O que o tempo limite de leitura definido como "infinito" significa? Em que situação ele pode permanecer em um loop infinito? O que pode provocar que o loop infinito termine?

Isso significa que uma chamada para reado fluxo do soquete pode ser bloqueada para sempre. Mais uma vez, não há loop infinito, mas readpode ser desbloqueado por uma Thread.interrupt()chamada, fechando o soquete e (é claro) a outra extremidade enviando dados ou fechando a conexão.


1 - Não é ... como um comentarista pensou ... o tempo limite de quanto tempo um soquete pode ser aberto ou ocioso.

Stephen C
fonte
8

Esses são valores de tempo limite impostos pela JVM para o estabelecimento da conexão TCP e aguardando a leitura de dados do soquete.

Se o valor estiver definido como infinito, você não esperará para sempre. Significa simplesmente que a JVM não possui tempo limite e o SO será responsável por todos os tempos limite. No entanto, os tempos limite no sistema operacional podem ser muito longos. Em uma rede lenta, já vi tempos limite de até 6 minutos.

Mesmo se você definir o valor do tempo limite para o soquete, ele poderá não funcionar se o tempo limite ocorrer no código nativo. Podemos reproduzir o problema no Linux conectando a um host bloqueado pelo firewall ou desconectando o cabo do switch.

A única abordagem segura para lidar com o tempo limite do TCP é executar o código de conexão em um thread diferente e interrompê-lo quando levar muito tempo.

ZZ Coder
fonte
"Se o valor estiver definido como infinito, você não esperará para sempre." Desde que não se trate de discussão sobre o significado de "infinito", pode com certeza acontecer que você espera muito, muito tempo. Tivemos um caso aqui, onde um HttpURLConnection.getResponseCode()estava pendurado por aproximadamente. uma semana até reiniciarmos o processo. Obviamente, não havia tempo limite definido no lado da JVM e também não houve tempo limite no lado do SO Linux.
21713 Tom Tom Fink
O parágrafo final não está correto. O tempo limite de uma conexão termina após aproximadamente um minuto. Um segmento separado é completamente desnecessário. Você certamente pode ter leituras que são executadas para sempre se não houver dados. No entanto, o Javadoc está errado quanto ao tempo limite de conexão padrão ser infinito. Não é.
Marquês de Lorne
1
@comeGetSome Isso não está correto. Você pode desligar o soquete para entrada. Isso fará com que a leitura bloqueada encontre o final do fluxo.
Marquês de Lorne #
@comeGetSome: eu tive que implementar isso usando um thread que contém uma referência a uma conexão de URL HTTP aberta. Quando o referido thread fecha a conexão, o outro thread lança "java.net.SocketException: Socket closed". Obrigado bug JDK-8075484 por me fazer fazer isso!
Fmcato
@comeGetSome Certamente você pode ligar Socket.shutdownInput()sem ter a mão na mão? NB Esses tempos limite são impostos pelo TCP, não pela JVM.
Marquês de Lorne