Estou recebendo o seguinte erro ao tentar ler de um soquete. Estou fazendo readInt()
isso InputStream
e estou recebendo esse erro. Examinando a documentação, isso sugere que a parte da conexão do cliente 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 eu estou fechando a conexão. Então, alguém tem uma idéia de por que isso está acontecendo? O que mais deve ser verificado? Isso ocorre quando existem recursos locais que talvez estejam atingindo limites?
Percebo que tenho a seguinte linha:
socket.setSoTimeout(10000);
pouco antes da readInt()
. Há uma razão para isso (longa história), mas apenas curioso, existem circunstâncias em que isso pode levar ao erro indicado? Eu tenho o servidor em execução no meu IDE e, por acaso, o deixei preso em um ponto de interrupção e, em seguida, notei que exatamente os mesmos erros começaram a aparecer em meus próprios logs no meu IDE.
De qualquer forma, apenas mencionando, espero que não seja um arenque vermelho. :-(
fonte
Respostas:
Existem várias causas possíveis.
A outra extremidade deliberadamente redefiniu a conexão, de uma maneira que não documentarei aqui. É raro e geralmente incorreto o software aplicativo fazer isso, mas não é desconhecido o software comercial.
Mais comumente, é causado pela gravação em uma conexão que a outra extremidade já foi fechada normalmente. Em outras palavras, um erro no protocolo do aplicativo.
Também pode ser causado pelo fechamento de um soquete quando houver dados não lidos no buffer de recebimento do soquete.
No Windows, o 'software causou a interrupção da conexão', que não é o mesmo que 'redefinição da conexão', é causado por problemas de rede ao enviar do seu lado. Há um artigo da base de conhecimento da Microsoft sobre isso.
fonte
A redefinição da conexão significa simplesmente que um TCP RST foi recebido. Isso acontece quando seu colega recebe dados que não podem ser processados e pode haver várias razões para isso.
O mais simples é quando você fecha o soquete e, em seguida, grava mais dados no fluxo de saída. Ao fechar o soquete, você disse ao seu colega que havia terminado de falar e ele pode esquecer sua conexão. De qualquer maneira, quando você envia mais dados nesse fluxo, o ponto a rejeita com um RST para que você saiba que não está ouvindo.
Em outros casos, um firewall intermediário ou até o próprio host remoto pode "esquecer" sua conexão TCP. Isso pode acontecer se você não enviar dados por um longo período de tempo (2 horas é um tempo limite comum) ou porque o par foi reiniciado 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:
Dê uma olhada no seu manuseio 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 o manipulador de exceções fechar o soquete e tentar gravar nele, você estará em uma condição de redefinição de conexão.setSoTimeout()
destina-se a fornecer uma maneira limpa de interromper umaread()
operação que poderia bloquear para sempre, sem fazer coisas sujas, como fechar o soquete de outro encadeamento.fonte
Sempre que tive problemas estranhos como esse, costumo me sentar com uma ferramenta como o WireShark e ver os dados brutos sendo transmitidos para frente e para trás. Você pode se surpreender onde as coisas estão sendo desconectadas e só será notificado quando tentar ler.
fonte
Vergonhoso dizer isso, mas quando tive esse problema, foi simplesmente um erro que eu estava fechando a conexão antes de ler todos os dados. Nos casos em que pequenas seqüências de caracteres foram retornadas, funcionou, mas isso provavelmente ocorreu porque toda a resposta foi armazenada em buffer antes de eu a fechar.
Nos casos em que quantidades maiores de texto são retornadas, a exceção foi lançada, pois mais do que um buffer estava retornando.
Você pode verificar essa supervisão. Lembre-se de abrir um URL é como um arquivo, feche-o (libere a conexão) depois que ele for totalmente lido.
fonte
Você deve inspecionar o rastreamento completo com muito cuidado,
Eu tenho um aplicativo de soquete de servidor e corrigi um
java.net.SocketException: Connection reset
caso.No meu caso, isso acontece durante a leitura de um
Socket
objeto clientSocket que está fechado sua conexão por algum motivo. (Rede perdida, falha no firewall ou no aplicativo ou fechamento pretendido)Na verdade, eu estava restabelecendo a conexão quando recebi um erro ao ler este objeto Socket.
O interessante é que,
for my JAVA Socket
se um cliente se conectar ao meuServerSocket
e fechar sua conexão sem enviar nada,is.read()
chama-se recursivamente. Parece que, por estar em um loop while infinito para ler a partir desse soquete, você tenta ler a partir de uma conexão fechada. Se você usar algo como abaixo para operação de leitura;Então você obtém um stackTrace algo como abaixo
O que fiz foi fechar o ServerSocket e renovar minha conexão, aguardando novas conexões de clientes.
Isso restabelece minha conexão para soquete de cliente desconhecido perde
Não consegui encontrar outra maneira porque, como você vê na imagem abaixo, não consegue entender se a conexão está perdida ou não sem a
try and catch
, porque tudo parece certo. Obtive este instantâneo enquanto estava obtendoConnection reset
continuamente.fonte
Eu tive o mesmo erro. Encontrei a solução para o problema agora. O problema era que o programa cliente estava sendo concluído antes do servidor ler os fluxos.
fonte
Eu tive esse problema com um sistema SOA escrito em Java. Eu estava executando o cliente e o servidor em máquinas físicas diferentes e eles funcionaram bem por um longo período de tempo. Em seguida, essas redefiniçõ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 e aumentamos a memória disponível para a JVM: problema resolvido! Observe que não havia OutOfMemoryError no log: a memória era escassa, não esgotada.
fonte
Verifique a versão Java do seu servidor. Aconteceu comigo porque meu Weblogic 10.3.6 estava no JDK 1.7.0_75, no TLSv1. O ponto final restante que eu estava tentando consumir estava desligando qualquer coisa abaixo do TLSv1.2.
Por padrão, o Weblogic estava tentando negociar o protocolo compartilhado mais forte. Veja detalhes aqui: Problemas com a configuração da propriedade do sistema https.protocols para conexões HTTPS .
Adicionei log SSL detalhado para identificar o TLS suportado. Isso indicava que o TLSv1 estava sendo usado para o aperto de mão.
-Djavax.net.debug=ssl:handshake:verbose:keymanager:trustmanager -Djava.security.debug=access:stack
Eu resolvi isso enviando o recurso para o nosso produto compatível com JDK8, o JDK8 padrão é TLSv1.2. Para aqueles restritos ao JDK7, também testei com êxito uma solução alternativa para o Java 7 atualizando para o TLSv1.2. Eu usei esta resposta: Como habilitar o TLS 1.2 no Java 7
fonte
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 funcionando bem, mas o método read () estava lançando um java.net.SocketException: Redefinição de conexão. Corrigi esse problema adicionando a chave SSH do cliente às chaves conhecidas do servidor remoto.
fonte
Na minha experiência, frequentemente encontro as seguintes situações;
Se você trabalha em uma empresa corporativa, entre em contato com a equipe de rede e segurança. Como em solicitações feitas a serviços externos, pode ser necessário conceder permissão para o terminal relevante.
Outro problema é que o certificado SSL pode ter expirado no servidor em que seu aplicativo está sendo executado.
fonte