Estou usando o cliente http apache commons para chamar url usando o método post para postar os parâmetros e está lançando o erro abaixo raramente.
java.net.SocketException: Broken pipe
at java.net.SocketOutputStream.socketWrite0(Native Method)
at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:92)
at java.net.SocketOutputStream.write(SocketOutputStream.java:136)
at java.io.BufferedOutputStream.write(BufferedOutputStream.java:105)
at java.io.FilterOutputStream.write(FilterOutputStream.java:80)
at org.apache.commons.httpclient.methods.ByteArrayRequestEntity.writeRequest(ByteArrayRequestEntity.java:90)
at org.apache.commons.httpclient.methods.EntityEnclosingMethod.writeRequestBody(EntityEnclosingMethod.java:499)
at org.apache.commons.httpclient.HttpMethodBase.writeRequest(HttpMethodBase.java:2114)
at org.apache.commons.httpclient.HttpMethodBase.execute(HttpMethodBase.java:1096)
at org.apache.commons.httpclient.HttpMethodDirector.executeWithRetry(HttpMethodDirector.java:398)
Alguém pode sugerir o que está causando essa exceção e como depurá-la?
Respostas:
Isso é causado por:
Portanto, nos dois casos, você possui um protocolo de aplicativo mal definido ou implementado.
Há uma terceira razão que não documentarei aqui, mas que envolve o ponto de executar ações deliberadas para redefinir em vez de fechar adequadamente a conexão.
fonte
XMLHttpRequest.abort()
).No nosso caso, experimentamos isso ao executar um teste de carga em nosso servidor de aplicativos. Ocorreu o problema de que precisamos adicionar memória adicional à nossa JVM porque ela estava acabando. Isso resolveu o problema.
Tente aumentar a memória disponível para a JVM e ou monitore o uso de memória quando receber esses erros.
fonte
SocketException: canal quebrado, é causado pelo 'outro lado' (o cliente ou o servidor) que fecha a conexão enquanto o seu código está lendo ou gravando na conexão.
Essa é uma exceção muito comum nos aplicativos cliente / servidor que recebem tráfego de clientes ou servidores fora do controle do aplicativo. Por exemplo, o cliente é um navegador. Se o navegador fizer uma chamada Ajax e / ou o usuário simplesmente fechar a página ou o navegador, isso poderá efetivamente eliminar toda a comunicação inesperadamente. Basicamente, você verá esse erro sempre que a outra extremidade finalizar o aplicativo e você não o esperava.
Se você tiver essa exceção no seu aplicativo, significa que deve verificar seu código onde a IO (entrada / saída) ocorre e envolvê-la com um bloco try / catch para capturar essa IOException. Cabe a você decidir como deseja lidar com essa situação semi-válida.
No seu caso, o primeiro local em que você ainda tem controle é a chamada para
HttpMethodDirector.executeWithRetry
- Portanto, assegure-se de que a chamada seja encerrada com o bloco try / catch e trate-a como achar melhor.Eu recomendaria fortemente contra o registro de erros específicos de SocketException-Broken Pipe em algo diferente de níveis de depuração / rastreamento. Senão, isso pode ser usado como uma forma de ataque do DOS (Denial Of Service), preenchendo os logs. Tente fortalecer e testar negativamente seu aplicativo para esse cenário comum.
fonte
Todos os fluxos e conexões abertos precisam ser fechados corretamente, portanto, da próxima vez que tentarmos usar o objeto urlConnection, ele não emitirá um erro. Como exemplo, a seguinte alteração de código corrigiu o erro para mim.
Antes:
Depois de:
fonte
BufferedOutputStream
sempre chamaclose()
seu fluxo de saída subjacente (portanto, o fluxo de saída deurlConnection
). Consulte docs.oracle.com/javase/6/docs/api/java/io/… e docs.oracle.com/javase/6/docs/api/java/io/… Portanto, quando você ligar,os.close()
já deve ter sido fechado . Não?Eu implementei a funcionalidade de download de dados através do servidor FTP e também encontrei a mesma exceção ao continuar o download. Para resolver essa exceção, você sempre precisará se desconectar da sessão anterior e criar uma nova instância do cliente e uma nova conexão com o servidor. Essa mesma abordagem também pode ser útil para o HTTPClient.
fonte
Eu tinha o mesmo problema enquanto desenvolvia um aplicativo Java simples que escuta um TCP específico. Normalmente, não tinha nenhum problema, mas quando executo algum teste de estresse, notei que alguma conexão quebrou com erro
socket write exception
.Após a investigação, encontrei uma solução que resolve meu problema. Sei que essa pergunta é bastante antiga, mas prefiro compartilhar minha solução, alguém pode achar útil.
O problema estava na criação do ServerSocket. Eu li no Javadoc, há um limite padrão de 50 soquetes pendentes. Se você tentar abrir outra conexão, elas serão recusadas. A solução consiste simplesmente em alterar essa configuração padrão no lado do servidor. No caso a seguir, crio um servidor de soquete que escuta na porta TCP
10_000
e aceita o máximo de200
soquetes pendentes.Do Javadoc do ServerSocket :
fonte
O problema pode ser que seus arquivos implantados não são atualizados com os métodos RMI corretos. Verifique se sua interface RMI possui parâmetros atualizados ou estruturas de dados atualizadas que seu cliente não possui. Ou que seu cliente RMI não possui parâmetros diferentes da versão do servidor.
Este é apenas um palpite. Depois de reimplantar os arquivos de classe do meu aplicativo de servidor e testar novamente, o problema do "Tubo quebrado" desapareceu.
fonte
As respostas acima ilustram o motivo disso
java.net.SocketException: Broken pipe
: a outra extremidade fechou a conexão. Gostaria de compartilhar a experiência do que aconteceu quando o encontrei:Content-Type
cabeçalho é definido erroneamente como maior que o corpo da solicitação (na verdade, não havia nenhum corpo)Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception java.net.SocketTimeoutException: null
java.net.SocketException: Broken pipe
porque o cliente fechou.Às vezes, o tomcat não lança uma exceção de pip quebrada, porque a exceção de tempo limite fecha a conexão, por que essa diferença está me confundindo também.
fonte
Content-Type
cabeçalho não especifica um número, portanto, não pode ser 'maior' do que qualquer coisa. Exceções de tempo limite não fecham o soquete. A resposta não faz nenhum sentido.Você deve aumentar o parâmetro "backlog" do seu ServerSocket, por exemplo
fonte
A causa é que o ponto remoto fecha seu soquete (falha por exemplo); portanto, se você tentar gravar dados nele, por exemplo, você obterá isso. para resolver isso, proteja as operações de leitura / gravação no soquete entre (tente pegar) e gerencie o caso de perda de conexão no problema (renove a conexão, pare o programa, etc. etc):
fonte