web-dev-qa-db-fra.com

Obtenir "SocketException: réinitialisation de la connexion par un pair" dans Android

Mon application doit contacter le même appareil sur lequel elle travaille, via http://127.0.0.1/... (une URL d'hôte local).

Pour une raison quelconque, environ 50% des fois (et peut-être exactement 50%) lorsque j'atteins un site Web avec du contenu JSON, j'obtiens l'exception:

Java.net.SocketException: échec de recvfrom: ECONNRESET (réinitialisation de la connexion par l'homologue)

Pour les 50% restants, j'obtiens des résultats parfaitement bons. J'ai essayé de faire des sondages (et même un grand délai entre les sondages), mais j'obtiens toujours les mêmes résultats étranges.

J'ai cherché sur Internet et aussi ici, et je ne sais pas pourquoi cela se produit. Le pair signifie-t-il que le client l'a causé? Pourquoi cela se produit-il et comment dois-je le gérer?

Certains sites Web disent que c'est une chose courante, mais je n'ai pas trouvé la meilleure chose à faire dans de tels cas.

39
android developer

D'accord, la réponse était que c'était la faute du serveur - il devait fermer la connexion après chaque demande.

Il se pourrait que Android conserve un pool de connexions et utilise l'ancien ou quelque chose comme ça.

Quoi qu'il en soit, maintenant cela fonctionne.


EDIT: selon l'API de HttpURLConnection, cela peut aussi être résolu côté client:

Les flux d'entrée et de sortie renvoyés par cette classe ne sont pas mis en mémoire tampon. La plupart des appelants doivent encapsuler les flux renvoyés avec BufferedInputStream ou BufferedOutputStream. Les appelants qui effectuent uniquement des lectures ou des écritures en bloc peuvent omettre la mise en mémoire tampon. Lors du transfert de grandes quantités de données vers ou depuis un serveur, utilisez des flux pour limiter la quantité de données en mémoire à la fois. Sauf si vous avez besoin que le corps entier soit en mémoire à la fois, traitez-le comme un flux (plutôt que de stocker le corps complet comme un tableau ou une chaîne à un octet).

Pour réduire la latence, cette classe peut réutiliser le même socket sous-jacent pour plusieurs paires demande/réponse. Par conséquent, les connexions HTTP peuvent rester ouvertes plus longtemps que nécessaire. Les appels à déconnecter () peuvent renvoyer le socket vers un pool de sockets connectés. Ce comportement peut être désactivé en définissant la propriété système http.keepAlive sur false avant d'émettre des requêtes HTTP. La propriété http.maxConnections peut être utilisée pour contrôler le nombre de connexions inactives à chaque serveur.

Tiré de: developer.Android.com/reference/Java/net/HttpURLConnection.html

21
android developer

Essayez de définir cette propriété pour votre HttpURLConnection avant de vous connecter:

conn.setRequestProperty("connection", "close");

Cela désactivera la propriété " keep-alive " qui est activée par défaut.

6
valerybodak

C'est un vieux fil que je connais. Mais cela pourrait aider quelqu'un.

Dans mon cas, cette erreur a été provoquée par le service .NET WCF (soap). L'un des objets dans le résultat renvoyé avait un DataMember avec la propriété get {} mais pas la propriété set {}.

Pour que la sérialisation se produise, chaque DataMember doit avoir à la fois {} et set {} disponibles. J'ai implémenté un ensemble vide {} (vide en raison de mes règles métier) et le problème a été résolu.

Mon scenerio est une mauvaise implémentation spécifique du serveur, mais cela aidera peut-être quelqu'un à gagner du temps lors du dépannage.

3
Cucumen

J'avais beaucoup de ces Connection reset by peer lorsque je visitais certaines pages Web ou téléchargeais des fichiers (à partir de mon application ou du navigateur Android).

Il s'est avéré que c'est mon opérateur 3G qui a bloqué les connexions (par exemple, le téléchargement d'un .exe le fichier a été interdit).

Avez-vous le même problème sur le Wifi?

1
Sébastien

dans ma situation, le problème a été résolu en nettoyant l'adresse proxy et le port d'APN qui a été produit par l'opérateur. comme je l'ai testé, l'utilisation de l'adresse IP du serveur distant au lieu du nom de domaine peut également résoudre le problème.

0
ahmad pj