170 votes

Comment réparer java.net.SocketException : Un tuyau cassé ?

J'utilise le client apache commons http pour appeler l'url en utilisant la méthode post pour envoyer les paramètres et l'erreur ci-dessous se produit rarement.

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)

Quelqu'un peut-il suggérer la cause de cette exception et comment la déboguer ?

92voto

EJP Points 113412

Ceci est causé par :

  • le plus souvent, l'écriture sur une connexion lorsque l'autre extrémité l'a déjà fermée ;
  • moins généralement, le pair ferme la connexion sans lire toutes les données qui sont déjà en attente à son extrémité.

Dans les deux cas, vous avez donc un protocole d'application mal défini ou mal mis en œuvre.

Il existe une troisième raison, que je ne décrirai pas ici, mais qui implique que l'homologue agit délibérément pour réinitialiser la connexion au lieu de la fermer correctement.

41voto

Dave Points 51

Dans notre cas, nous avons rencontré ce problème en effectuant un test de charge sur notre serveur d'applications. Le problème s'est avéré que nous devions ajouter de la mémoire supplémentaire à notre JVM car elle était en train de s'épuiser. Cela a résolu le problème.

Essayez d'augmenter la mémoire disponible pour la JVM ou surveillez l'utilisation de la mémoire lorsque vous obtenez ces erreurs.

10voto

AndyGee Points 227

SocketException : Broken pipe, est causé par la fermeture de la connexion par l'autre partie (le client ou le serveur) pendant que votre code lit ou écrit dans la connexion.

Il s'agit d'une exception très courante dans les applications client/serveur qui reçoivent du trafic en provenance de clients ou de serveurs hors du contrôle de l'application. Par exemple, le client est un navigateur. Si le navigateur effectue un appel Ajax, et/ou si l'utilisateur ferme simplement la page ou le navigateur, cela peut effectivement tuer toute communication de manière inattendue. En fait, vous verrez cette erreur chaque fois que l'autre extrémité met fin à son application et que vous ne l'avez pas anticipé.

Si vous rencontrez cette exception dans votre application, cela signifie que vous devez vérifier votre code à l'endroit où l'IO (entrée/sortie) se produit et l'entourer d'un bloc try/catch pour attraper cette IOException. C'est ensuite à vous de décider comment vous voulez gérer cette situation semi-valide.

Dans votre cas, le premier endroit où vous avez encore le contrôle est l'appel à HttpMethodDirector.executeWithRetry - Assurez-vous donc que cet appel est entouré du bloc try/catch et traitez-le comme bon vous semble.

Je vous déconseille fortement d'enregistrer les erreurs spécifiques à SocketException-Broken Pipe autrement qu'à des niveaux de débogage/trace. Sinon, cela peut être utilisé comme une forme d'attaque DOS (Denial Of Service) en remplissant les journaux. Essayez de renforcer et de tester négativement votre application pour ce scénario courant.

5voto

Murali Mohan Points 29

Tous les flux et connexions ouverts doivent être correctement fermés, de sorte que la prochaine fois que nous essayons d'utiliser l'objet urlConnection, il n'y ait pas d'erreur. Par exemple, le changement de code suivant a corrigé l'erreur pour moi.

Avant :

OutputStream out = new BufferedOutputStream(urlConnection.getOutputStream());
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(out));
bw.write("Some text");
bw.close();
out.close();

Après :

OutputStream os = urlConnection.getOutputStream();
OutputStream out = new BufferedOutputStream(os);
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(out));
bw.write("Some text");
bw.close();
out.close();
os.close(); // This is a must.

1voto

Naeem Ahmad Points 11

J'ai mis en place une fonctionnalité de téléchargement de données via un serveur FTP et j'ai trouvé la même exception lors de la reprise du téléchargement. Pour résoudre cette exception, vous devrez toujours vous déconnecter de la session précédente et créer une nouvelle instance du client et une nouvelle connexion avec le serveur. Cette même approche pourrait être utile pour HTTPClient également.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X