Ce qui peut provoquer l'apparition spontanée d'un EPIPE erreur sans fin l'appel à close() ou de s'écraser?
J'ai une application qui se compose de deux processus (appelons-les A et B), reliés les uns aux autres à travers des sockets de domaine Unix. La plupart du temps, il fonctionne très bien, mais certains utilisateurs signalent le problème suivant:
- Un envoie une demande à B. Cela fonctionne. Aujourd'hui commence la lecture de la réponse de B.
- B envoie une réponse à A. Le correspondant write() qui renvoie une erreur EPIPE, et comme un résultat B close() de la douille. Cependant, Un fait pas close() de la douille, ni crash.
- Un read() renvoie 0, indiquant la fin-de-fichier. Un pense que B prématurément fermé la connexion.
Les utilisateurs ont également signalé des variations de ce comportement, par exemple:
- Un envoie une demande à B. Cela fonctionne partiellement, mais avant de l'ensemble de la demande est envoyée à l'Un de write() appel renvoie EPIPE, et en conséquence, une close() de la douille. Cependant B n'est pas close() de la douille, ni crash.
- B lit partielle d'une demande, puis devient soudainement un EOF.
Le problème est que je ne peut pas reproduire ce comportement à l'échelle locale à tous. J'ai essayé OS X et Linux. Les utilisateurs sont sur une variété de systèmes, principalement OS X et Linux.
Choses que j'ai déjà essayé et examiné:
- Double close() de bugs (close() est appelée deux fois sur le même descripteur de fichier): probablement pas que le résultat serait de EBADF erreurs, mais je ne les ai pas vu.
- Augmenter le nombre maximum de descripteurs de fichiers limite. Un utilisateur a signalé que ce qui a fonctionné pour lui, le reste a signalé qu'il n'a pas.
Quoi d'autre peut éventuellement provoquer un comportement comme ça? Je sais bien que ni A, ni B close() la prise prématurément, et je sais que pour certain qu'aucun d'entre eux ont écrasé parce que A et B ont été en mesure de rendre compte de l'erreur. C'est comme si le noyau a soudainement décidé de retirer la fiche de la prise pour une raison quelconque.
OriginalL'auteur Hongli | 2010-02-10
Vous devez vous connecter pour publier un commentaire.
Peut-être que vous pourriez essayer strace comme décrit dans: http://modperlbook.org/html/6-9-1-Detecting-Aborted-Connections.html
Je suppose que votre problème est lié à celui décrit ici: http://blog.netherlabs.nl/articles/2009/01/18/the-ultimate-so_linger-page-or-why-is-my-tcp-not-reliable
Malheureusement, je vais avoir un problème similaire moi-même, mais ne parvenais pas à obtenir fixe avec le donné des conseils. Cependant, peut-être que SO_LINGER chose qui fonctionne pour vous.
Pas exactement la réponse que je cherchais, mais le TCP page, vous lien est très instructif! C'est maintenant par Archive.org toujours a ça: ia700609.us.archive.org/22/items/...
OriginalL'auteur user206268
shutdown()
peut avoir été appelé sur l'un des
douille d'extrémité.
Si l'une des parties peut fourche et d'exécuter un
processus enfant, s'assurer que le
FD_CLOEXEC
(close-on-exec) indicateur est défini sur l'
prise descripteur de fichier si vous n'avez pas
l'intention qu'il sera héritée par l'
enfant. Sinon, le processus de l'enfant
pourrait (accidentellement ou non) être
la manipulation de votre connexion de socket.
OriginalL'auteur mark4o
Je voudrais aussi vérifier qu'il n'y a pas de pare-feu sournois dans le milieu. Il est possible qu'un intermédiaire nœud de transfert sur la route envoie un
RST
. La meilleure façon de s'assurer que le bas est bien sûr le renifleur de paquets (ou de ses GUI cousin.)Oh ... merde, je l'ai totalement oubliée. Merci.
OriginalL'auteur Nikolai Fetissov