Raisons officielles de l’abandon de la connexion par le logiciel: erreur d’écriture du socket

157

Étant donné cet extrait de trace de pile

Provoqué par: java.net.SocketException: le logiciel a provoqué l'abandon de la connexion: erreur d'écriture de socket
 sur java.net.SocketOutputStream.socketWrite0 (méthode native)

J'ai essayé de répondre aux questions suivantes:

  1. Quel code lève cette exception? (JVM? / Tomcat? / Mon code?)
  2. Qu'est-ce qui provoque la levée de cette exception?

Concernant le n ° 1:

La source JVM de Sun ne contient pas ce message exact, mais je pense que le texte Software a causé l'abandon de la connexion: l'erreur d'écriture de socket provient de l'implémentation native de SocketOutputStream:

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

Concernant # 2

Je suppose que cela est causé lorsque le client a mis fin à la connexion, avant d'obtenir la réponse complète (par exemple, a envoyé une demande, mais avant d'obtenir la réponse complète, elle a été fermée / terminée / hors ligne)

Des questions:

  1. Les hypothèses ci-dessus sont-elles correctes (n ° 1 et n ° 2)?
  2. Cela peut-il être différent de la situation: "impossible d'écrire sur le client en raison d'une erreur réseau côté serveur "? ou cela rendrait-il le même message d'erreur?
  3. Et le plus important: existe-t-il un document officiel (par exemple de Sun) indiquant ce qui précède?

J'ai besoin d'une preuve que cette trace de pile est la "faute" du client socket, et il n'y a rien que le serveur aurait pu faire pour l'éviter. (sauf pour attraper l'exception, ou en utilisant un SocketOutputStream non Sun JVM, bien que les deux n'évitent pas vraiment le fait que le client s'est arrêté)

Eran Medan
la source
J'ai ce problème lors de l'annulation d'un téléchargement avec Firefox
koppor
Hey Eran, je reçois également cette exception en envoyant / écrivant ( outs.write(audioBytes);) byte[]à OutputStream. Lorsque l'audio s'exécute et pendant la lecture si l'utilisateur clique sur un autre menu (qui envoie une requête au serveur), j'ai eu la même erreur sur la console. alors est-il prudent d'ignorer cette exception?
Amogh
1
@Amogh - Il semble que oui. Fondamentalement, d'après ce que les réponses décrivent, il s'agit d'une erreur spécifique à Windows, mais je suppose que sous Linux, vous obtiendrez la même exception juste avec un libellé différent ... (Ma compréhension des termes profanes est essentiellement que cela est causé lorsque vous envoyez via une prise vers un emplacement distant X et X se sont déconnectés au milieu, mais je suis sûr que ce n'est pas la façon la plus précise de le décrire)
Eran Medan
1
Pour moi, cela s'est produit lorsque le serveur de base de données a été redémarré et que l'application essayait toujours d'interroger en utilisant des connexions précédemment ouvertes. Je ne sais pas pourquoi ils n'ont pas été actualisés car nous utilisons la mise en commun basée sur DBCP. Mais le redémarrage de l'application a résolu le problème.
Kshitiz Sharma

Réponses:

55

Cette erreur peut se produire lorsque le système de réseau local abandonne une connexion, par exemple lorsque WinSock ferme une connexion établie après l'échec de la retransmission des données (le récepteur n'acquitte jamais les données envoyées sur un socket de flux de données).

Consultez cet article MSDN . Voir aussi Quelques informations sur «Le logiciel a provoqué l'interruption de la connexion» .

Marquis de Lorne
la source
3
@MatGessel Cet article ne fait que répéter la confusion et en ajoute quelques-uns. WSAECONNABORTED est un code d'erreur Winsock, il ne peut donc pas y avoir d'explication Berkeley. La situation décrite à propos du serveur HTTP produirait ECONNRESET, pas WSAECONNABORTED.
Marquis of Lorne
@EJP, j'obtiens également cette exception en envoyant / en écrivant (outs.write (audioBytes);) octet [] dans OutputStream. Lorsque l'audio s'exécute et pendant la lecture si l'utilisateur clique sur un autre menu (qui envoie une requête au serveur), j'ai eu la même erreur sur la console. alors est-il prudent d'ignorer cette exception?
Amogh
1
@rustyx Les trois sources citées ici indiquent qu'il est produit par des échecs ACK. Si vous avez une source pour votre propre réclamation, veuillez la citer.
Marquis de Lorne
2
Ce n'est pas une vraie réponse car cela ne vous donne pas d'informations pour approfondir le problème. La réponse ici est essentiellement "quelque chose de grave s'est produit sur le réseau". Il serait vraiment utile de comprendre quels autres journaux et autres enregistrements d'activité pourraient me permettre d'identifier le problème sous-jacent.
Derek Bennett
11

Le java.net.SocketExceptionest émis lorsqu'il y a une erreur lors de la création ou de l'accès à un socket (tel que TCP ). Cela peut généralement se produire lorsque le serveur a mis fin à la connexion (sans la fermer correctement), donc avant d'obtenir la réponse complète. Dans la plupart des cas, cela peut être causé soit par le problème du délai d'attente (par exemple, la réponse prend trop de temps ou le serveur est surchargé avec les demandes), soit par le client a envoyé le SYN, mais il n'a pas reçu ACK (accusé de réception de la fin de la connexion) . Pour les problèmes de délai d'expiration, vous pouvez envisager d'augmenter la valeur du délai d'expiration.

L'exception de socket est généralement accompagnée du message de détail spécifié sur le problème.

Exemple de messages détaillés:

  • Le logiciel a provoqué l'interruption de la connexion: échec de la recv.

    L'erreur indique une tentative d'envoi du message et la connexion a été interrompue par votre serveur. Si cela s'est produit lors de la connexion à la base de données, cela peut être lié à l'utilisation d'un pilote JDBC Connector / J non compatible .

    Solution possible: assurez-vous d'avoir les bibliothèques / pilotes appropriés dans votre CLASSPATH.

  • Le logiciel a provoqué l'interruption de la connexion: connectez-vous.

    Cela peut se produire lorsqu'il y a un problème de connexion à la télécommande. Par exemple en raison du virus-checker rejetant les demandes de courrier distant .

    Solution possible: vérifiez si le service d'analyse antivirus bloque le port pour les demandes de connexions sortantes.

  • Le logiciel a provoqué l'abandon de la connexion: erreur d'écriture du socket.

    Solution possible: assurez-vous que vous écrivez la bonne longueur d'octets dans le flux. Vérifiez donc ce que vous envoyez. Voir ce fil .

  • Réinitialisation de la connexion par l'homologue: erreur d'écriture du socket / Connexion interrompue par l'homologue: erreur d'écriture du socket

    L'application n'a pas vérifié si la connexion persistante avait expiré du côté serveur.

    Solution possible: assurez-vous que HttpClient est non nul avant de lire à partir de la connexion. E13222_01

  • Réinitialisation de la connexion par paire.

    La connexion a été interrompue par le pair (serveur).

  • Connexion réinitialisée.

    La connexion a été interrompue par le client ou fermée par l'extrémité serveur de la connexion en raison de la demande avec la demande.

    Voir: Qu'est-ce qui cause mon java.net.SocketException: réinitialisation de la connexion?

Kenorb
la source
Un seul de ces 6 points répond effectivement à la question, de manière incorrecte. Plusieurs autres sont également incorrects. L'application ne peut pas «vérifier si la connexion persistante a expiré du côté serveur». L' HttpClientêtre nullne peut pas provoquer de SocketException. Ne pas écrire la longueur correcte dans le flux non plus.
Marquis of Lorne le
9

J'ai vu cela le plus souvent lorsqu'un pare-feu d'entreprise sur un poste de travail / ordinateur portable gêne la connexion.

par exemple. J'ai un processus serveur et un processus client sur la même machine. Le serveur écoute sur toutes les interfaces (0.0.0.0) et le client tente une connexion à l'interface public / home (notez pas l'interface de bouclage 127.0.0.1).

Si la machine a son réseau déconnecté (par exemple, le wifi est désactivé), la connexion est établie. Si la machine est connectée au réseau d'entreprise (directement ou VPN), la connexion est établie.

Cependant, si la machine est connectée à un wifi public (ou à un réseau domestique), le pare-feu déclenche la connexion. Dans cette situation, la connexion du client à l'interface de bouclage fonctionne correctement, mais pas à l'interface home / public.

J'espère que cela t'aides.

user2028913
la source
3
Les pare-feu empêchent les connexions. La question est de réinitialiser une connexion existante.
Marquis of Lorne
4

Pour prouver quel composant échoue, je surveillerais la communication TCP / IP à l'aide de WireShark et regarderais qui ferme effectivement le port, des délais d'expiration pourraient également être pertinents.

empileur
la source
Personne ne ferme le port. Le système d'exploitation abandonne la connexion.
Marquis de Lorne
@EJP J'ai vu cela se produire lorsque le est surchargé et manque de mémoire. Je ne suis pas sûr que ce soit le système d'exploitation qui ferme la connexion, mais JVM se déchaîne.
Zee
1
@Zee Il y a une différence entre la fermeture d'un port, qui est visible en tant que FIN dans Wireshark, et l'abandon de la connexion, ce qui ne l'est pas.
Marquis de Lorne
2

Avez-vous vérifié le code source Tomcat et la source JVM? Cela peut vous aider davantage.

Je pense que votre réflexion générale est bonne. Je m'attendrais ConnectExceptionà ce que vous ne puissiez pas vous connecter dans le scénario. Ce qui précède semble très axé sur le client.

Brian Agnew
la source
3
Oui, j'ai vérifié. Les sources de Tomcat ne contenaient aucune permutation de la phrase, merci.
Eran Medan
1
Non, il n'a pas vérifié la source Tomcat ET la source JVM.
Stephen C
Ou s'il a vérifié la source JVM, il ne l'a pas entièrement vérifiée.
Stephen C
1
@Ehrann - la chaîne de message est probablement dans les sources natives. Mais vous devriez également vérifier le journal des événements. IMO, ce dernier sera probablement plus informatif.
Stephen C
6
Cette chaîne de message provient en fait du système d'exploitation.
Marquis de Lorne
2

Pour quiconque utilise de simples programmes client-serveur et obtient cette erreur, il s'agit d'un problème de flux d'entrée ou de sortie non fermés (ou fermés au début).

PRO_gramista
la source
2
Non, ça ne l'est pas. Cela consisterait en une fuite de socket, ce qui finirait par provoquer un épuisement FD.
Marquis de Lorne
0

J'étais confronté au même problème.
Généralement, ce type d'erreur se produit parce que le client a fermé sa connexion et que le serveur essaie toujours d'écrire sur ce client.
Assurez-vous donc que votre client a sa connexion ouverte jusqu'à ce que le serveur ait terminé avec son flux de sortie.
Et encore une chose, n'oubliez pas de fermer les flux d'entrée et de sortie.

J'espère que cela t'aides.
Et si le problème persiste, informez-en votre problème ici en détail.

Nirav Chhatrola
la source
3
@BhavinChhatrola Non, une réponse incorrecte. La situation décrite produit «réinitialisation de la connexion par le pair», et non l'erreur dans la question.
Marquis of Lorne le
0

Cette erreur m'est arrivée lors du test de mon service soap avec le client SoapUI, en gros, j'essayais d'obtenir un très gros message (> 500kb) et SoapUI a fermé la connexion par timeout.

Sur SoapUI, allez à:

Fichier -> Préférences - Délai d'expiration du socket (ms)

... et mettez une valeur élevée, telle que 180000 (3 minutes), ce ne sera pas la solution idéale pour votre problème car le fichier est en fait trop volumineux, mais au moins vous aurez une réponse.

Marco
la source
0

Connexion fermée dans un autre client

Dans mon cas, l'erreur était:

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

Il a été reçu dans eclipse lors du débogage d'une application java accédant à une base de données H2. La source de l'erreur était que j'avais initialement ouvert la base de données avec SQuirreL pour vérifier manuellement l'intégrité. J'ai utilisé le drapeau pour activer plusieurs connexions à la même base de données (c.-à-d.AUTO_SERVER=TRUE ), il n'y a donc pas eu de problème de connexion à la base de données depuis java.

L'erreur est apparue quand, après un certain temps - c'est un long processus java - j'ai décidé de fermer SQuirreL pour libérer des ressources. Il semble que SQuirreL était celui qui «possédait» l'instance de serveur de base de données et qu'il avait été arrêté avec la connexion SQuirreL.

Le redémarrage de l'application Java n'a pas renvoyé l'erreur.

config

  • Windows 7
  • Eclipse Kepler
  • SQuirreL 3.6
  • org.h2.Driver ver 1.4.192
manuelvigarcia
la source
0

Dans mon cas, j'ai développé le côté client et côté serveur, et j'ai l'exception:

Cause: arguments de rassemblement d'erreur; l'exception imbriquée est: java.net.SocketException: le logiciel a provoqué l'abandon de la connexion: erreur d'écriture du socket

lorsque les classes du client et du serveur sont différentes. Je ne télécharge pas les classes du serveur (Interfaces) sur le client, je rajoute juste les mêmes fichiers dans le projet. Mais le chemin doit être exactement le même. Par exemple, sur le projet serveur, j'ai des packages java \ rmi \ services avec une interface et des implémentations de service, je dois créer le même package sur le projet client. Si je le change par java / rmi / server / services par exemple, j'obtiens l'exception ci-dessus. Même exception si la version de l'interface est différente entre le client et le serveur (même avec une ligne vide ajoutée par inadvertance ... je pense que rmi fait une sorte de hachage de classes pour vérifier la version ... je ne sais pas ... si cela pouvait Aidez-moi ...

Elloco
la source
-1

Mon serveur lançait cette exception dans les 2 jours et je l'ai résolue en déplaçant la fonction de déconnexion avec:

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

À la fin du fil de discussion. si cela peut aider quelqu'un.

Sefi Erlich
la source
-1

Dans la situation expliquée ci-dessous, le côté client lèvera une telle exception:

Le serveur est invité à authentifier le certificat client, mais le client fournit un certificat dont l'utilisation étendue de la clé ne prend pas en charge l'authentification du client, de sorte que le serveur n'accepte pas le certificat du client, puis ferme la connexion.

xiaoming
la source
Cette réponse est incorrecte. Dans le cas où vous décrivez une SSLException sera lancée.
Président James K. Polk
en fait, il jette SocketException tout comme la question actuelle, j'avais testé
xiaoming
-1

Le côté client ssl lancera une telle exception dans la situation ci-dessous (j'avais testé),:

Le serveur est invité à authentifier le certificat client, mais le client fournit un certificat dont l'utilisation étendue de la clé ne prend pas en charge l'authentification client.

xiaoming
la source
-3

J'étais confronté au même problème avec wireMock tout en se moquant des autres appels d'API. Plus tôt, je définissais le serveur comme ceci:

WireMockServer wireMockServer = null;

Mais il doit être défini comme indiqué ci-dessous:

@Rule 
public WireMockRule wireMockRule = new WireMockRule(8089);
Yallaling Goudar
la source
Cela poserait un NullPointerExceptionproblème, pas ce problème.
Marquis of Lorne le