J'obtiens l'erreur suivante en essayant de lire à partir d'un socket. Je fais une readInt()
sur ce InputStream
, et j'obtiens cette erreur. En parcourant la documentation, cela suggère que la partie client de la connexion a fermé la connexion. Dans ce scénario, je suis le serveur.
J'ai accès aux fichiers journaux du client et il ne ferme pas la connexion, et en fait ses fichiers journaux suggèrent que je ferme la connexion. Quelqu'un a-t-il une idée de la raison pour laquelle cela se produit ? Que faut-il vérifier d'autre ? Cela se produit-il lorsque des ressources locales atteignent peut-être des seuils ?
Je note que j'ai la ligne suivante :
socket.setSoTimeout(10000);
juste avant le readInt()
. Il y a une raison à cela (longue histoire), mais par curiosité, y a-t-il des circonstances dans lesquelles cela pourrait conduire à l'erreur indiquée ? J'ai le serveur qui tourne dans mon IDE, et il se trouve que j'ai laissé mon IDE bloqué sur un point d'arrêt, et j'ai alors remarqué que les mêmes erreurs exactement ont commencé à apparaître dans mes propres journaux dans mon IDE.
Quoi qu'il en soit, je ne fais que le mentionner, en espérant qu'il ne s'agit pas d'un faux-fuyant :-(
Il y a plusieurs causes possibles.
L'autre extrémité a délibérément réinitialisé la connexion, d'une manière que je ne décrirai pas ici. Il est rare, et généralement incorrect, qu'un logiciel d'application fasse cela, mais ce n'est pas inconnu pour les logiciels commerciaux.
Plus communément, il est causé par l'écriture sur une connexion que l'autre extrémité a déjà fermée normalement. En d'autres termes, il s'agit d'une erreur de protocole d'application.
Elle peut également être causée par la fermeture d'une socket lorsqu'il y a des données non lues dans le tampon de réception de la socket.
Sous Windows, l'abandon de la connexion causé par le logiciel, qui n'est pas la même chose que la réinitialisation de la connexion, est causé par des problèmes de réseau de votre côté. Il existe un article de la base de connaissances de Microsoft à ce sujet.
La réinitialisation de la connexion signifie simplement qu'un TCP RST a été reçu. Cela se produit lorsque votre homologue reçoit des données qu'il ne peut pas traiter, et il peut y avoir plusieurs raisons à cela.
La raison la plus simple est que vous fermez le socket, puis écrivez d'autres données sur le flux de sortie. En fermant le socket, vous dites à votre pair que vous avez fini de parler et qu'il peut oublier votre connexion. Lorsque vous envoyez quand même d'autres données sur ce flux, le pair les rejette avec un RST pour vous faire savoir qu'il n'écoute pas.
Dans d'autres cas, un pare-feu intermédiaire ou l'hôte distant lui-même peut oublier votre connexion TCP. Cela peut se produire si vous n’envoyez pas de données pendant une longue période (un délai de 2 heures est courant), ou parce que le pair a été redémarré et a perdu ses informations sur les connexions actives. L'envoi de données sur l'une de ces connexions défuntes provoquera également un RST.
Mise à jour en réponse à des informations supplémentaires:
Examinez attentivement votre gestion de l'exception SocketTimeoutException
. Cette exception est levée si le délai d'attente configuré est dépassé pendant le blocage d'une opération de socket. L'état de la socket elle-même n'est pas modifié lorsque cette exception est levée, mais si votre gestionnaire d'exception ferme la socket, et essaie ensuite d'y écrire, vous serez dans une condition de réinitialisation de la connexion. setSoTimeout()
est censé vous donner un moyen propre de sortir d'une opération read()
qui pourrait autrement bloquer pour toujours, sans faire des choses sales comme fermer le socket depuis un autre thread.
Chaque fois que j'ai eu des problèmes bizarres comme celui-ci, je m'assois généralement avec un outil comme [WireShark][1] et je regarde les données brutes qui passent dans les deux sens. Vous pourriez être surpris de voir où les choses sont déconnectées et où vous n'êtes notifié que lorsque vous essayez de lire.