Razões oficiais para "O software causou a interrupção da conexão: erro de gravação do soquete"

157

Dado esse snippet de rastreamento de pilha

Causado por: java.net.SocketException: O software causou a interrupção da conexão: erro de gravação de soquete
 em java.net.SocketOutputStream.socketWrite0 (método nativo)

Tentei responder às seguintes perguntas:

  1. Qual código está lançando essa exceção? (JVM? / Tomcat? / Meu código?)
  2. O que faz com que essa exceção seja lançada?

Em relação ao item 1:

A fonte JVM da Sun não contém essa mensagem exata, mas acho que o texto Software causou uma interrupção na conexão: erro de gravação de soquete é da implementação nativa de SocketOutputStream:

private native void socketWrite0(FileDescriptor fd, byte[] b, int off,
                 int len) throws IOException;

Em relação a # 2

Meu palpite é que isso é causado quando o cliente encerra a conexão, antes de obter a resposta completa (por exemplo, envia uma solicitação, mas antes de obter a resposta completa, ela é fechada / finalizada / offline)

Questões:

  1. As premissas acima estão corretas (nº 1 e nº 2)?
  2. Isso pode ser diferenciado da situação: "não foi possível gravar no cliente devido a um erro de rede no servidor "? ou isso renderizaria a mesma mensagem de erro?
  3. E o mais importante: existe um documento oficial (por exemplo, da Sun) afirmando o acima?

Eu preciso ter uma prova de que esse rastreamento de pilha é a "falha" do cliente de soquete e não há nada que o servidor possa ter feito para evitá-lo. (exceto capturando a exceção ou usando um JVM SocketOutputStream que não seja da Sun, embora ambos não evitem o fato de o cliente ter terminado)

Eran Medan
fonte
Eu tenho esse problema ao cancelar um download com o Firefox
koppor
Hey Eran, também estou recebendo essa exceção ao enviar / escrever ( outs.write(audioBytes);) byte[]para OutputStream. Quando o áudio está tocando e durante a reprodução, se o usuário clicar em qualquer outro menu (que envia uma solicitação do servidor), recebi o mesmo erro no console. então é seguro ignorar essa exceção?
Amogh
1
@ Amogh - Parece que sim. Basicamente, pelo que as respostas descrevem, esse é um erro específico do Windows, mas eu suponho que no Linux você terá a mesma exceção apenas com uma expressão diferente ... através de uma tomada para algum local remoto X e X foi desconectado no meio, mas tenho certeza que não é a maneira mais precisa para descrevê-lo)
Eran Medan
1
Para mim, isso aconteceu quando o servidor de banco de dados foi reiniciado e o aplicativo ainda estava tentando consultar usando conexões abertas anteriormente. Não sei por que eles não foram atualizados, pois estamos usando o pool baseado em DBCP. Mas reiniciar o aplicativo corrigiu o problema.
Kshitiz Sharma

Respostas:

55

Este erro pode ocorrer quando o sistema de rede local interrompe uma conexão, como quando o WinSock fecha uma conexão estabelecida após a retransmissão de dados falhar (o receptor nunca reconhece os dados enviados no soquete do fluxo de dados).

Veja este artigo do MSDN . Consulte também Algumas informações sobre 'Interrupção de conexão causada por software' .

Marquês de Lorne
fonte
3
@ MatGessel Esse artigo apenas repete a confusão e adiciona algumas próprias. WSAECONNABORTED é um código de erro do Winsock, portanto, não pode haver uma explicação para Berkeley. A situação descrita sobre o servidor HTTP produziria ECONNRESET, não WSAECONNABORTED.
Marquês de Lorne
@EJP, também estou recebendo essa exceção ao enviar / gravar (outs.write (audioBytes);) byte [] para OutputStream. Quando o áudio está tocando e durante a reprodução, se o usuário clicar em qualquer outro menu (que envia uma solicitação do servidor), recebi o mesmo erro no console. então é seguro ignorar essa exceção?
219 Amogh
1
@rustyx Todas as três fontes citadas aqui afirmam que são produzidas por falhas no ACK. Se você tem uma fonte para sua própria reivindicação, cite-a.
Marquês de Lorne
2
Esta não é uma resposta real, pois não fornece informações para aprofundar o problema. A resposta aqui é basicamente "algo de ruim aconteceu na rede". Seria realmente útil entender o que outros logs e outros registros de atividades poderiam me permitir identificar o problema subjacente.
Derek Bennett
11

A java.net.SocketExceptioné acionada quando há um erro ao criar ou acessar um soquete (como TCP ). Isso geralmente pode ser causado quando o servidor encerra a conexão (sem fechá-la corretamente), portanto, antes de obter a resposta completa. Na maioria dos casos, isso pode ser causado pelo problema de tempo limite (por exemplo, a resposta leva muito tempo ou o servidor está sobrecarregado com as solicitações) ou o cliente enviou o SYN, mas não recebeu ACK (reconhecimento da terminação da conexão) . Para problemas de tempo limite, considere aumentar o valor do tempo limite.

A exceção de soquete geralmente vem com a mensagem de detalhes especificada sobre o problema.

Exemplo de mensagens detalhadas:

  • O software causou a interrupção da conexão: falha na recuperação.

    O erro indica uma tentativa de enviar a mensagem e a conexão foi interrompida pelo seu servidor. Se isso aconteceu durante a conexão com o banco de dados, isso pode estar relacionado ao uso do driver Connector / J JDBC não compatível .

    Solução possível: verifique se você possui bibliotecas / drivers adequados no seu CLASSPATH.

  • Interrupção de conexão causada por software: conectar.

    Isso pode acontecer quando houver um problema para conectar-se ao controle remoto. Por exemplo, devido à verificação de vírus que rejeitou as solicitações de correio remoto .

    Solução possível: verifique se o serviço de verificação de vírus está bloqueando a porta para as solicitações de saída de conexões.

  • O software causou a interrupção da conexão: erro de gravação do soquete.

    Solução possível: verifique se você está escrevendo o tamanho correto de bytes no fluxo. Então verifique o que você está enviando. Veja este tópico .

  • Redefinição de conexão por ponto: erro de gravação de soquete / Conexão interrompida por ponto: erro de gravação de soquete

    O aplicativo não verificou se a conexão keep-alive havia atingido o tempo limite no servidor.

    Solução possível: verifique se o HttpClient é não nulo antes de ler a partir da conexão. E13222_01

  • Redefinição de conexão por pares.

    A conexão foi encerrada pelo par (servidor).

  • Reinicialização da conexão.

    A conexão foi encerrada pelo cliente ou fechada pelo final do servidor devido a solicitação com a solicitação.

    Consulte: O que está causando meu java.net.SocketException: Conexão redefinida?

kenorb
fonte
Apenas um desses 6 pontos responde à pergunta incorretamente. Vários outros também estão incorretos. O aplicativo não pode 'verificar se a conexão keep-alive foi atingida pelo tempo limite do servidor'. O HttpClientser nullnão pode causar a SocketException. Também não é possível escrever o comprimento correto no fluxo.
Marquês de Lorne
9

Eu já vi isso com mais frequência quando um firewall corporativo em uma estação de trabalho / laptop atrapalha, mata a conexão.

por exemplo. Eu tenho um processo de servidor e um processo de cliente na mesma máquina. O servidor está escutando em todas as interfaces (0.0.0.0) e o cliente tenta uma conexão com a interface pública / home (observe a interface de loopback 127.0.0.1).

Se a máquina estiver com a rede desconectada (por exemplo, wifi desligado), a conexão será formada. Se a máquina estiver conectada à rede corporativa (diretamente ou VPN), a conexão será formada.

No entanto, se a máquina estiver conectada a um wifi público (ou rede doméstica), o firewall entra em ação e mata a conexão. Nessa situação, conectar o cliente à interface de loopback funciona bem, mas não à interface doméstica / pública.

Espero que isto ajude.

user2028913
fonte
3
Os firewalls impedem conexões. A questão é redefinir uma conexão existente.
Marquês de Lorne
4

Para provar qual componente falha, eu monitorava a comunicação TCP / IP usando o wireshark e olhava quem está fechando completamente a porta, também os intervalos podem ser relevantes.

empilhador
fonte
Ninguém está fechando a porta. O sistema operacional está cancelando a conexão.
Marquês de Lorne #
@EJP Eu já vi isso acontecer quando o computador fica sobrecarregado e fica sem memória. Não tenho certeza de que é o sistema operacional que fecha a conexão, mas a JVM fica louca.
Zee
1
@Zee Há uma diferença entre fechar uma porta, que é visível como FIN no Wireshark, e interromper a conexão, o que não é.
Marquês de Lorne
2

Você verificou o código-fonte do Tomcat e a fonte da JVM? Isso pode lhe dar mais ajuda.

Eu acho que o seu pensamento geral é bom. Eu esperaria um ConnectExceptionno cenário que você não conseguiu conectar. O acima parece muito orientado para o cliente.

Brian Agnew
fonte
3
Sim, eu verifiquei. As fontes do Tomcat não continham nenhuma permutação da frase, obrigado.
Eran Medan
1
Não, ele não verificou a fonte do Tomcat E a fonte da JVM.
Stephen C
Ou, se ele verificou a fonte da JVM, ele não verificou tudo.
Stephen C
1
@Ehrann - a sequência de mensagens é mais provável nas fontes nativas. Mas você também deve verificar o log de eventos. Na OMI, é provável que este último seja mais informativo.
Stephen C
6
Essa sequência de mensagens vem do sistema operacional, na verdade.
Marquês de Lorne
2

Para quem usa programas simples do Client Server e obtém esse erro, é um problema de fluxos de entrada ou saída não fechados (ou fechados para o início).

PRO_gramista
fonte
2
Não, não é. Isso consitaria um vazamento de soquete, o que acabaria causando uma exaustão de DF.
Marquês de Lorne
0

Eu estava enfrentando o mesmo problema.
Comumente Esse tipo de erro ocorre porque o cliente fechou sua conexão e o servidor ainda está tentando gravar nesse cliente.
Portanto, verifique se o seu cliente tem sua conexão aberta até o servidor concluir o fluxo de saída.
E mais uma coisa, não se esqueça de fechar o fluxo de entrada e saída.

Espero que isto ajude.
E se ainda estiver enfrentando um problema, informe-o aqui em detalhes.

Nirav Chhatrola
fonte
3
@BhavinChhatrola Não, uma resposta incorreta. A situação descrita produz 'redefinição de conexão por ponto', não o erro na pergunta.
Marquês de Lorne
0

Este erro aconteceu comigo ao testar meu serviço de sabão com o cliente SoapUI, basicamente eu estava tentando receber uma mensagem muito grande (> 500kb) e o SoapUI fechou a conexão por tempo limite.

No SoapUI, acesse:

Arquivo -> Preferências - Tempo limite do soquete (ms)

... e coloque um valor grande, como 180000 (3 minutos), essa não será a correção perfeita para o seu problema, pois o arquivo é realmente grande demais, mas pelo menos você terá uma resposta.

Marco
fonte
0

Conexão fechada em outro cliente

No meu caso, o erro foi:

java.net.SocketException: Software caused connection abort: recv failed

Foi recebido no eclipse durante a depuração de um aplicativo java acessando um banco de dados H2. A origem do erro foi que eu havia aberto o banco de dados com o SQuirreL para verificar manualmente a integridade. Eu usei o sinalizador para habilitar várias conexões com o mesmo banco de dados (ou seja AUTO_SERVER=TRUE), portanto não houve problema em conectar-se ao banco de dados a partir de java.

O erro apareceu quando, depois de um tempo - é um longo processo java -, decidi fechar o SQuirreL para liberar recursos. Parece que SQuirreL foi o "proprietário" da instância do servidor DB e que foi encerrada com a conexão SQuirreL.

Reiniciar o aplicativo Java não produziu o erro novamente.

config

  • Windows 7
  • Eclipse Kepler
  • SQuirreL 3.6
  • org.h2.Driver versão 1.4.192
manuelvigarcia
fonte
0

No meu caso, desenvolvi o lado do cliente e do servidor e tenho a exceção:

Causa: erro ao organizar argumentos; A exceção aninhada é: java.net.SocketException: o software causou a interrupção da conexão: erro de gravação do soquete

quando as classes no cliente e no servidor são diferentes. Não baixo as classes do servidor (Interfaces) no cliente, apenas adiciono os mesmos arquivos no projeto. Mas o caminho deve ser exatamente o mesmo. Por exemplo, no projeto do servidor, eu tenho pacotes java \ rmi \ services com alguns serviceInterface e implementações, preciso criar o mesmo pacote no projeto do cliente. Se eu mudar por java / rmi / server / services, por exemplo, recebo a exceção acima. Mesma exceção se a versão da interface for diferente entre cliente e servidor (mesmo com uma linha vazia adicionada inadvertidamente ... acho que o rmi faz uma espécie de hash de classes para verificar a versão ... não sei ... se pudesse Socorro ...

Elloco
fonte
-1

Meu servidor estava lançando essa exceção nos últimos dois dias e resolvi-a movendo a função desconectar com:

outputStream.close();
inputStream.close();
Client.close();

Até o final do segmento da lista. se isso ajudou alguém.

Sefi Erlich
fonte
-1

Na situação explicada abaixo, o lado do cliente lançará uma exceção:

O servidor é solicitado a autenticar o certificado do cliente, mas o cliente fornece um certificado cujo uso estendido de chave não oferece suporte à autenticação do cliente; portanto, o servidor não aceita o certificado do cliente e fecha a conexão.

xiaoming
fonte
Esta resposta está incorreta. No caso de você descrever uma exceção SSLEx, será lançada.
Presidente James K. Polk
na verdade, ele lança SocketException, assim como a pergunta atual, eu tinha testado #
28419
-1

O lado do cliente ssl lançará essa exceção na situação abaixo (eu testei):

o servidor é solicitado a autenticar o certificado do cliente, mas o cliente fornece um certificado que o uso estendido de chave não oferece suporte à autenticação do cliente.

xiaoming
fonte
-3

Eu estava enfrentando o mesmo problema com o wireMock enquanto zombava das demais chamadas da API. Anteriormente, eu estava definindo o servidor assim:

WireMockServer wireMockServer = null;

Mas deve ser definido como mostrado abaixo:

@Rule 
public WireMockRule wireMockRule = new WireMockRule(8089);
Yallaling Goudar
fonte
Isso causaria um NullPointerExceptionproblema, não esse.
Marquês de Lorne