java.net.SocketException: conexão redefinida

Estou recebendo o seguinte erro ao tentar ler de um soquete. Eu estou fazendo um readInt() nesse InputStream , e estou recebendo este erro. Examinando a documentação, isso sugere que a parte cliente da conexão fechou a conexão. Nesse cenário, eu sou o servidor.

Eu tenho access aos arquivos de log do cliente e ele não está fechando a conexão e, de fato, seus arquivos de log sugerem que estou fechando a conexão. Então, alguém tem uma idéia do porquê isso está acontecendo? O que mais para verificar? Isso ocorre quando há resources locais que talvez estejam atingindo limites?


Eu noto que tenho a seguinte linha:

 socket.setSoTimeout(10000); 

pouco antes do readInt() . Há uma razão para isso (longa história), mas apenas curioso, há circunstâncias em que isso pode levar ao erro indicado? Eu tenho o servidor em execução no meu IDE, e por acaso deixei meu IDE preso em um ponto de interrupção, e então percebi que exatamente os mesmos erros começaram a aparecer em meus próprios logs no meu IDE.

Enfim, apenas mencionando, espero que não seja um arenque vermelho. 🙁

Existem várias causas possíveis.

  1. A outra extremidade deliberadamente redefiniu a conexão, de uma maneira que não documentarei aqui. É raro, e geralmente incorreto, que o software aplicativo faça isso, mas não é desconhecido para software comercial.

  2. Mais comumente, é causado por gravar em uma conexão que a outra extremidade já encerrou normalmente. Em outras palavras, um erro de protocolo de aplicativo.

  3. Também pode ser causado pelo fechamento de um soquete quando houver dados não lidos no buffer de recebimento do soquete.

  4. No Windows, ‘o software causou a interrupção da conexão’, que não é o mesmo que ‘reboot da conexão’, é causado por problemas de rede enviados pelo seu lado. Há um artigo da base de conhecimento da Microsoft sobre isso.

A redefinição de conexão significa simplesmente que um TCP RST foi recebido. Isso acontece quando seu colega recebe dados que não podem processar e pode haver vários motivos para isso.

O mais simples é quando você fecha o soquete e grava mais dados no stream de saída. Ao fechar a tomada, você disse ao seu colega que acabou de falar e pode esquecer sua conexão. Quando você envia mais dados nesse stream, o peer o rejeita com um RST para informar que ele não está escutando.

Em outros casos, um firewall intermediário ou até mesmo o próprio host remoto pode “esquecer” sua conexão TCP. Isso pode acontecer se você 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 desativadas também causará um RST.


Atualizar em resposta a informações adicionais:

SocketTimeoutException sua manipulação do SocketTimeoutException . Essa exceção é gerada se o tempo limite configurado for excedido enquanto bloqueado em uma operação de soquete. O estado do soquete em si não é alterado quando essa exceção é lançada, mas se seu manipulador de exceção fechar o soquete e tentar gravar nele, você estará em uma condição de reconfiguração de conexão. setSoTimeout() serve para dar a você uma maneira limpa de sair de uma operação read() que poderia ser bloqueada para sempre, sem fazer coisas sujas como fechar o socket de outro thread.

Sempre que tive problemas estranhos como esse, geralmente me sento com uma ferramenta como o WireShark e vejo os dados brutos sendo transmitidos de um lado para outro. Você pode se surpreender quando as coisas estão sendo desconectadas, e você só está sendo notificado quando você tenta ler.

Embaraçoso para dizer isso, mas quando eu tive esse problema, foi simplesmente um erro que eu estava fechando a conexão antes de ler todos os dados. Nos casos com pequenas strings sendo retornadas, funcionava, mas isso provavelmente se devia ao fato de toda a resposta ter sido armazenada em buffer, antes de fechá-la.

Nos casos de maior quantidade de texto sendo retornado, a exceção foi lançada, já que mais de um buffer estava retornando.

Você pode verificar essa supervisão. Lembre-se de abrir um URL é como um arquivo, certifique-se de fechá-lo (liberar a conexão), uma vez que foi totalmente lido.

Você deve inspecionar o traço completo com muito cuidado,

Eu tenho um aplicativo de soquete do servidor e corrigido um java.net.SocketException: Connection reset caso de java.net.SocketException: Connection reset .

No meu caso, isso acontece durante a leitura de um object Socket cliente, que é fechado por causa de alguma razão. (Perda de rede, falha de firewall ou aplicativo ou fechamento pretendido)

Na verdade, eu estava restabelecendo a conexão quando recebi um erro durante a leitura deste object Socket.

 Socket clientSocket = ServerSocket.accept(); is = new BufferedReader(new InputStreamReader(clientSocket.getInputStream())); int readed = is.read(); // WHERE ERROR STARTS !!! 

O interessante é for my JAVA Socket se um cliente se conecta ao meu ServerSocket e fechar sua conexão sem enviar nada is.read() chama-se recursivamente.Parece que por estar em um loop while infinito para leitura deste socket você tenta ler de uma conexão fechada. Se você usar algo como abaixo para operação de leitura;

 while(true) { Receive(); } 

Então você começa um stackTrace algo como abaixo e sobre

 java.net.SocketException: Socket is closed at java.net.ServerSocket.accept(ServerSocket.java:494) 

O que eu fiz foi fechar o ServerSocket e renovar minha conexão e esperar por mais conexões de input do cliente

 String Receive() throws Exception { try { int readed = is.read(); .... }catch(Exception e) { tryReConnect(); logit(); //etc } //... } 

Isso reestabliza minha conexão para perda de soquete do cliente desconhecido

 private void tryReConnect() { try { ServerSocket.close(); //empty my old lost connection and let it get by garbage col. immediately clientSocket=null; System.gc(); //Wait a new client Socket connection and address this to my local variable clientSocket= ServerSocket.accept(); // Waiting for another Connection System.out.println("Connection established..."); }catch (Exception e) { String message="ReConnect not successful "+e.getMessage(); logit();//etc... } } 

Eu não consegui encontrar outro jeito, porque como você pode ver na imagem abaixo, você não pode entender se a conexão está perdida ou não, sem try and catch , porque tudo parece certo. Eu obtive este instantâneo enquanto eu estava recebendo a Connection reset continuamente.

insira a descrição da imagem aqui

Eu tive o mesmo erro. Eu encontrei a solução para o problema agora. O problema era que o programa do cliente estava terminando antes de o servidor ler os streams.

Eu tive esse problema com um sistema SOA escrito em Java. Eu estava executando tanto o cliente quanto o servidor em diferentes máquinas físicas e eles funcionaram bem por um longo tempo, então essas reseções de conexão desagradáveis ​​apareceram no log do cliente e não havia nada de estranho no log do servidor. Reiniciar o cliente e o servidor não resolveu o problema. Finalmente, descobrimos que o heap no lado do servidor estava cheio, então aumentamos a memory disponível para a JVM: problema resolvido! Observe que não havia OutOfMemoryError no log: a memory era apenas escassa, não esgotada.

Eu também tive esse problema com um programa Java tentando enviar um comando em um servidor via SSH. O problema estava na máquina que executava o código Java. Não tinha permissão para se conectar ao servidor remoto. O método write () estava indo bem, mas o método read () estava lançando um java.net.SocketException: Connection reset. Eu consertei esse problema adicionando a chave SSH do cliente às chaves conhecidas do servidor remoto.