J'ai une application qui se compose de deux processus (appelons-les A et B), connectés les uns aux autres via des sockets de domaine Unix. La plupart du temps cela fonctionne très bien, mais certains utilisateurs signalent le comportement suivant:Qu'est-ce qui peut provoquer une erreur EPIPE spontanée sans que l'un des deux finisse par appeler close() ou s'écraser?
- A envoie une requête à B. Cela fonctionne. A commence à lire la réponse de B.
- B envoie une réponse à A. L'appel write() correspondant renvoie une erreur EPIPE, et par conséquent B close() le socket. Cependant, A a fait pas fermer() le socket, et il ne s'est pas écrasé.
- L'appel de read() renvoie 0, indiquant la fin du fichier. A pense que B a fermé prématurément la connexion.
Les utilisateurs ont également signalé des variations de ce comportement, par exemple:
- A envoie une demande à B. Cela fonctionne en partie, mais avant toute la demande est envoyée appel en écriture() d'un retour EPIPE et en conséquence A close() le socket. Cependant, B n'a pas fermé() le socket, et il ne s'est pas écrasé.
- B lit une requête partielle et obtient soudainement un EOF.
Le problème est que je ne peux pas reproduire ce comportement localement. J'ai essayé OS X et Linux. Les utilisateurs sont sur une variété de systèmes, principalement OS X et Linux.
choses que je l'ai déjà essayé et estimais:
- fermer des bogues Double() (close() est appelée deux fois sur le même descripteur de fichier): probablement pas que cela entraînerait des erreurs de EBADF, mais Je ne les ai pas vus.
- Augmentation de la limite maximale du descripteur de fichier. Un utilisateur a rapporté que cela a fonctionné pour lui, le reste a rapporté que ce n'était pas le cas.
Quoi d'autre peut éventuellement provoquer un comportement comme celui-ci? Je sais avec certitude que ni A ni B ne ferment prématurément le socket, et je sais avec certitude qu'aucun d'entre eux ne s'est écrasé parce que A et B ont pu signaler l'erreur. C'est comme si le noyau avait soudainement décidé de retirer la fiche de la prise pour une raison quelconque.
Il s'est avéré que le descripteur de fichier du serveur a été ajouté avec l'indicateur EPOLLET à la file d'attente epoll qui semble être fausse. – user206268
Pas exactement la réponse que je cherchais mais la page TCP à laquelle vous vous êtes connecté est très instructive! Il est en baisse maintenant par Archive.org l'a toujours: http://ia700609.us.archive.org/22/items/TheUltimateSo_lingerPageOrWhyIsMyTcpNotReliable/the-ultimate-so_linger-page-or-why-is-my-tcp-not-reliable .html – Hongli