web-dev-qa-db-fra.com

Comment résoudre "Connexion réinitialisée par un pair: erreur d'écriture de socket"?

Lorsque je lis le contenu du fichier sur le serveur, le message d'erreur suivant s'affiche:

Caused by: Java.net.SocketException: Connection reset by peer: socket write error
at Java.net.SocketOutputStream.socketWrite0(Native Method)
at Java.net.SocketOutputStream.socketWrite(Unknown Source)
at Java.net.SocketOutputStream.write(Unknown Source)
at org.Apache.coyote.http11.InternalOutputBuffer.realWriteBytes(InternalOutputBuffer.Java:215)
at org.Apache.Tomcat.util.buf.ByteChunk.flushBuffer(ByteChunk.Java:462)
at org.Apache.Tomcat.util.buf.ByteChunk.append(ByteChunk.Java:366)
at org.Apache.coyote.http11.InternalOutputBuffer$OutputStreamOutputBuffer.doWrite(InternalOutputBuffer.Java:240)
at org.Apache.coyote.http11.filters.ChunkedOutputFilter.doWrite(ChunkedOutputFilter.Java:119)
at org.Apache.coyote.http11.AbstractOutputBuffer.doWrite(AbstractOutputBuffer.Java:192)
at org.Apache.coyote.Response.doWrite(Response.Java:504)
at org.Apache.catalina.connector.OutputBuffer.realWriteBytes(OutputBuffer.Java:383)
... 28 more

et mon programme de servlet est

 response.setContentType("application/octet-stream");
 response.setHeader("Content-Disposition","attachment;filename="+filename);
 FileInputStream in = new FileInputStream(new File(filepath));
 ServletOutputStream output=response.getOutputStream();
 byte[] outputByte=new byte[4096];
 while(in.read(outputByte,0,4096)!=-1){
     output.write(outputByte,0,4096);//error indicates in this line
 }
 in.close();
 output.flush();
 output.close();

Comment résoudre ce problème?

19
Babu R

J'ai la même exception et dans mon cas, le problème était dans un processus de renégociation. En fait, mon client a fermé une connexion lorsque le serveur a tenté de modifier une suite de chiffrement. Après avoir creusé, il apparaît que dans le processus de renégociation de jdk 1.6 update 22 est désactivé par défaut . Si vos contraintes de sécurité le permettent, essayez d'activer la renégociation non sécurisée en définissant la propriété système Sun.security.ssl.allowUnsafeRenegotiation sur true. Voici quelques informations sur le processus:

La renégociation de session est un mécanisme du protocole SSL permettant à permet au client ou au serveur de déclencher une nouvelle négociation SSL pendant une communication SSL en cours. La renégociation a été initialement conçue en tant que un mécanisme pour augmenter la sécurité d'un canal SSL en cours, par déclencher le renouvellement des clés de chiffrement utilisées pour sécuriser ce canal . Cependant, cette mesure de sécurité n'est pas nécessaire avec la cryptographie moderne algorithmes. En outre, la renégociation peut être utilisée par un serveur pour demander un certificat client (afin d'exécuter l'authentification du client ) lorsque le client tente d'accéder à un fichier protégé spécifique ressources sur le serveur.

De plus, il y a le excellent post à propos de cette question dans les détails et écrit dans un langage compréhensible (IMHO).

11
Dmitry

Le socket a été fermé par le client (navigateur).

Un bug dans votre code:

byte[] outputByte=new byte[4096];
while(in.read(outputByte,0,4096)!=-1){
   output.write(outputByte,0,4096);
}

Le dernier paquet lu, puis écrit peut avoir une longueur <4096, donc je suggère:

byte[] outputByte=new byte[4096];
int len;
while(( len = in.read(outputByte, 0, 4096 )) > 0 ) {
   output.write( outputByte, 0, len );
}

Ce n'est pas votre question, mais c'est ma réponse ... ;-)

3
Aubin

J'ai eu le même problème avec une petite différence:

L'exception a été levée au moment de la chasse

C'est un problème différent de stackoverflow . La brève explication était un paramètre d'en-tête de réponse incorrect:

response.setHeader ("Content-Encoding", "gzip");

malgré le contenu des données de réponse non compressé.

La connexion a donc été fermée par le navigateur.

0
Kayvan Tehrani

La bonne façon de le «résoudre» est de fermer la connexion et d’oublier le client. Le client a fermé la connexion pendant que vous écriviez encore, donc il ne veut pas vous connaître, alors c'est ça, n'est-ce pas?

0
user207421

Il semble que votre problème puisse survenir à

while(in.read(outputByte,0,4096)!=-1){

où il pourrait aller dans une boucle infinie pour ne pas avancer le décalage (qui est toujours 0 dans l'appel). Essayer

while(in.read(outputByte)!=-1){

qui essayera par défaut de lire jusqu’à outputByte.length dans le byte[]. De cette façon, vous n'avez pas à vous soucier de l'offset. Voir méthode de lecture de FileInputStrem

0
prajeesh kumar