168 votes

Raisons officielles pour "Software caused connection abort : socket write error" (Le logiciel a provoqué l'abandon de la connexion : erreur d'écriture de la socket)

Étant donné cet extrait de trace de pile

Causé par : java.net.SocketException : Le logiciel a provoqué l'abandon de la connexion : erreur d'écriture de la socket
 à l'adresse java.net.SocketOutputStream.socketWrite0(Méthode native méthode)

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

  1. Quel code génère cette exception ? (JVM?/Tomcat?/Mon code ?)
  2. Qu'est-ce qui provoque l'apparition de cette exception ?

Concernant le numéro 1 :

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

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

Concernant le point 2

Je pense que cela se produit lorsque le client a mis fin à la connexion avant d'avoir obtenu la réponse complète (par exemple, il a envoyé une demande, mais avant d'obtenir la réponse complète, la connexion a été fermée/terminée/hors ligne).

Questions :

  1. Les hypothèses ci-dessus sont-elles correctes (#1 et #2) ?
  2. Peut-on différencier cela de la situation : "Impossible d'écrire au client, en raison d'une erreur de réseau sur le serveur ou cela donnerait-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'avoir une preuve que cette trace de pile est la "faute" du client de socket, et il n'y a rien que le serveur aurait pu faire pour l'éviter. (sauf attraper l'exception, ou utiliser un SocketOutputStream non Sun JVM, bien que les deux n'évitent pas vraiment le fait que le client se soit terminé).

0 votes

Je rencontre ce problème lorsque j'annule un téléchargement avec Firefox.

0 votes

Hé Eran, j'obtiens également cette exception lors de l'envoi/écriture ( outs.write(audioBytes); ) byte[] à OutputStream . Lorsque l'audio est en cours de diffusion, si l'utilisateur clique sur un autre menu (ce qui envoie une requête au serveur), j'obtiens la même erreur sur la console. est-il possible d'ignorer cette exception ?

1 votes

@Amogh - Il semble que oui. 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, mais avec une formulation différente... (Ma compréhension en termes de profanes est que cela est causé par un envoi via un socket à un emplacement distant X et que X a été déconnecté au milieu, mais je suis sûr que ce n'est pas la façon la plus précise de le décrire).

57voto

EJP Points 113412

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'accuse jamais réception des données envoyées sur une socket datastream).

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

4 votes

3 votes

@MatGessel Cet article ne fait que répéter la confusion, et en ajoute une autre. 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, et non WSAECONNABORTED.

0 votes

@EJP, j'obtiens également cette exception lors de l'envoi/écriture (outs.write(audioBytes) ;) de byte[] dans OutputStream. Lorsque l'audio est en cours de lecture, si l'utilisateur clique sur un autre menu (ce qui envoie une requête au serveur), j'obtiens la même erreur sur la console. Est-il possible d'ignorer cette exception ?

10voto

user2028913 Points 11

J'ai constaté ce phénomène le plus souvent lorsqu'un pare-feu d'entreprise sur un poste de travail/ordinateur portable s'interpose, ce qui bloque la connexion.

eg. 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 de se connecter à l'interface publique/domicile (attention, pas l'interface de bouclage 127.0.0.1).

Si le réseau de la machine est déconnecté (par exemple, le wifi est désactivé), la connexion est établie. Si la machine est connectée au réseau de l'entreprise (directement ou par un réseau privé virtuel), la connexion est établie.

Toutefois, si la machine est connectée à un réseau wifi public (ou à un réseau domestique), le pare-feu entre en jeu et bloque la connexion. Dans cette situation, la connexion du client à l'interface de bouclage fonctionne bien, mais pas à l'interface domestique/publique.

J'espère que cela vous aidera.

3 votes

Pare-feu prévenir connexions. La question porte sur la réinitialisation d'une connexion existante.

4voto

stacker Points 34209

Pour prouver quel composant échoue, je surveillerais la communication TCP/IP en utilisant wireshark et regarder qui ferme effectivement le port, les délais d'attente peuvent également être pertinents.

0 votes

Personne ne ferme le port. Le système d'exploitation interrompt la connexion.

0 votes

@EJP J'ai vu cela se produire lorsque le système 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 la JVM se déchaîne.

1 votes

@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, qui ne l'est pas.

2voto

Carlos Heuberger Points 11804

Cela se produit également lorsque la connexion a été interrompue au lieu de normalement terminé .

Pas très bien documenté, mais l'appel à Socket.close() entraîne l'interruption de la connexion. Cela entraîne cette exception du côté de l'autre connexion, au lieu de générer une condition EOF pendant la lecture.

Editar: Appel à Socket.close() dans un thread pendant qu'un autre lit ou écrit dans cette socket, une exception est levée puisque la socket a été fermée.

A commencer une séquence normale de fin de connexion TCP, le client (ou le serveur) doit appeler Socket.shutdownOutput() , voir le javadoc ici . Cela provoque l'obtention d'un EOF de l'autre côté si la lecture se fait à partir du Socket, ce qui devrait également être suivi d'un appel à shutdownOutput() avant la fermeture, il est évident que plus aucune sortie ne doit être écrite sur cette socket.

1voto

Brian Agnew Points 143181

Avez-vous vérifié le code source de Tomcat y la source de la JVM ? Cela pourrait vous aider davantage.

Je pense que votre réflexion générale est bonne. Je m'attendrais à un ConnectException dans le scénario où vous ne pouviez pas vous connecter. Ce qui précède ressemble beaucoup à un problème de client.

3 votes

Oui, j'ai vérifié. Les sources de Tomcat ne contenaient aucune permutation de la phrase, merci.

1 votes

Non, il n'a pas vérifié les sources de Tomcat. ET la source de la JVM.

0 votes

Ou s'il a vérifié la source de la JVM, il ne l'a pas vérifiée entièrement.

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