Est-il prudent de lire depuis le tuyau OU la paire de douilles en fermant une extrémité jusqu’à atteindre EOF?

Considérez le code EXEMPLE suivant:

#include  int main() { int sv[ 2 ] = { 0 }; socketpair( AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0, sv ); for( unsigned ii = 0; ii  0 ) { delete msg; } return 0; } 

De toute évidence, le code fonctionne bien, mais cela ne signifie pas que ce n’est pas UB.

Impossible de trouver quoi que ce soit dans les pages de manuel, ce qui garantit que, lorsque sv[ 0 ] est fermé, la read sera toujours capable de tout lire depuis sv[ 1 ] , envoyé par l’ send .


Peut-être que la question pourrait être posée comme ceci – comme read renvoie 0 pour EOF et que socketpair est SOCK_STREAM , je suppose que EOF sera “touché” une fois que tout aura été lu depuis le socket et que l’autre côté sera fermé. Est-ce correct?

Autant que je sache, ça peut marcher, mais ça sent UB.

La bonne façon est la fermeture gracieuse :

  • shutdown(s, 1) ou (meilleur shutdown(s, SHUT_WR) )
  • lire jusqu’à la fin en entrée
  • alors seulement appeler à proximité.

(Références: http://msdn.microsoft.com/en-us/library/windows/desktop/ms738547%28v=vs.85%29.aspx , Socket de serveur Graceful Shutdown sous Linux )

Modifier :

Après avoir lu le commentaire R .., je me suis demandé si je n’étais pas un peu confus, ai fait quelques tests et lu à nouveau la documentation. Et… je pense maintenant que ce que j’ai dit est vrai pour l’utilisation d’une socket en général (inclure les sockets AF_INET), mais pas pour le socketpair AF_INET spécial.

Mon test a mis un peu plus de stress sur le système, puisque j’envoie 8 paquets de 1024 octets sur un système FreeBSD 9. Je me suis arrêté là car en envoyer plus aurait bloqué. Et après la fermeture de sv [0], je pouvais lire avec succès mes 8 paquets.

Donc, cela fonctionne sur des kernelx différents, mais ne trouve pas de référence valide, à part que les sockets AF_UNIX ne supportent pas les données OOB.

Je pourrais également confirmer que l’utilisation de shutdown fonctionne bien.

Conclusion: En ce qui me concerne, je me contenterais d’un arrêt progressif pour la fermeture d’un socket, mais surtout parce que je ne veux pas penser au protocole sous-jacent.

J’espère que quelqu’un d’autre avec plus de connaissances pourrait donner une documentation de référence