java.net.SocketException: Reinicialização da conexão

Estou a receber o seguinte erro ao tentar ler a partir de uma tomada. I'estou fazendo um readInt() nesse InputStream, e estou recebendo esse erro. Percebendo a documentação, isto sugere que a parte cliente da conexão fechou a conexão. Neste cenário, eu sou o servidor.

Eu tenho acesso aos arquivos de log do cliente e ele não está fechando a conexão, e na verdade seus arquivos de log sugerem que eu estou fechando a conexão. Então alguém tem alguma ideia do porquê disto estar a acontecer? O que mais verificar? Isto surge quando existem recursos locais que talvez estejam a atingir os limites?


Eu notei que eu tenho a seguinte linha:

socket.setSoTimeout(10000);

um pouco antes da readInt(). Há uma razão para isto (longa história), mas apenas curioso, existem circunstâncias sob as quais isto possa levar ao erro indicado? Eu tenho o servidor rodando no meu IDE, e por acaso eu deixei meu IDE preso em um ponto de parada, e então notei exatamente os mesmos erros começando a aparecer nos meus próprios logs no meu IDE.

De qualquer forma, apenas mencionando, espero que não seja um engano. :-(

Há várias causas possíveis.

  1. O outro extremo reiniciou deliberadamente a ligação, de uma forma que não vou documentar aqui. É raro, e geralmente incorreto, que software de aplicação faça isso, mas não é desconhecido para software comercial.

  2. Mais comumente, é causado pela escrita a uma conexão que a outra extremidade já fechou normalmente. Em outras palavras, um erro de protocolo de aplicação.

  3. Também pode ser causado pelo fechamento de um soquete quando há dados não lidos no buffer de recepção do soquete.

  4. No Windows, 'software causou o aborto da conexão' que não é o mesmo que 'reset da conexão', é causado por problemas de rede enviados a partir do seu fim. Aí'é um artigo da base de conhecimento da Microsoft sobre isto.

Comentários (1)

O reset da conexão significa simplesmente que um TCP RST foi recebido. Isto acontece quando o seu par recebe dados que ele pode't processar, e pode haver várias razões para isso.

O mais simples é quando você fecha a tomada, e depois escreve mais dados no fluxo de saída. Ao fechar o socket, você diz ao seu colega que já não fala mais e ele pode esquecer a sua ligação. Quando você envia mais dados naquele stream de qualquer maneira, o par o rejeita com um RST para que você saiba que está't ouvindo.

Em outros casos, um firewall ou mesmo o próprio host remoto pode "esqueça" sobre sua conexão TCP. Isso pode acontecer se você não'não enviar nenhum dado por um longo tempo (2 horas é um tempo limite comum), ou porque o par foi reinicializado e perdeu suas informações sobre conexões ativas. O envio de dados em uma dessas conexões defuntas também causará um RST.


Atualizar em resposta a informações adicionais:

Dê uma olhada de perto no seu manuseio do SocketTimeoutException'. Esta exceção é levantada se o timeout configurado for excedido enquanto bloqueado em uma operação de soquete. O estado do socket em si não é alterado quando esta excepção é lançada, mas se o seu manipulador de excepções fechar o socket, e depois tentar escrever para ele, você'estará numa condição de reset da ligação. OsetSoTimeout()destina-se a lhe dar uma maneira limpa de sair de uma operaçãoread()` que de outra forma poderia bloquear para sempre, sem fazer coisas sujas como fechar o soquete de outra thread.

Comentários (2)

Sempre que tenho tido problemas estranhos como este, normalmente sento-me com uma ferramenta como WireShark e olho para os dados brutos que estão a ser passados para trás e para a frente. Você pode se surpreender onde as coisas estão sendo desconectadas, e você só está sendo notificado quando você tenta ler.

Comentários (0)