it-swarm-pt.tech

java.net.SocketException: conexão redefinida

Estou recebendo o seguinte erro ao tentar ler de um soquete. Eu estou fazendo um readInt() naquele 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 acesso 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á recursos locais que talvez estejam atingindo limites?


Eu noto que tenho a seguinte linha:

socket.setSoTimeout(10000);

logo antes da 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. :-(

101
Darryl

Existem várias causas possíveis.

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

  2. Mais comumente, é causado por gravar em uma conexão que a outra extremidade já fechou 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 'reinicialização da conexão', é causado por problemas de rede enviados pelo seu lado. Há um artigo da base de conhecimento da Microsoft sobre isso.

100
user207421

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 fluxo 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 fluxo, 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 peer 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.


Atualização em resposta a informações adicionais:

Observe atentamente 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 esta exceção é lançada, mas se o 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() destina-se a 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 soquete de outro thread.

41
erickson

Sempre que tenho problemas estranhos como esse, geralmente sento-me com uma ferramenta como 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ê está apenas sendo notificado ao tentar ler.

13
GEOCHET

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, funcionou, mas isso provavelmente se deveu a toda a resposta ter sido armazenada antes de fechá-la.

Nos casos de maior quantidade de texto sendo retornado, a exceção foi lançada, pois mais de um buffer estava voltando.

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.

8
Scott S

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

Eu tenho um aplicativo de soquete de servidor e consertei um caso Java.net.SocketException: Connection reset.

No meu caso, isso acontece durante a leitura de um objeto clientSocket Socket que é fechado por causa de algum motivo. (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 objeto 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 fecha 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 entrada 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 um try and catch, porque tudo parece correto. Eu obtive este instantâneo enquanto eu estava recebendo Connection reset continuamente.

enter image description here

7
Davut Gürbüz

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 fluxos.

5
kml_ckr

Eu tive esse problema com um sistema SOAescrito 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 resets 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 memória disponível para a JVM: problema resolvido! Note que não havia OutOfMemoryError no log: a memória era apenas escassa, não esgotada.

4
Pino

Eu também tive esse problema com um programa Java tentando enviar um comando em um servidor via SSH. O problema estava com a máquina executando 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.

1
pmartin8