Quelles sont les causes de l'erreur ENOTCONN?
Je suis actuellement le maintien d'un logiciel de serveur web et j'ai besoin d'effectuer un grand nombre d'opérations d'e/S. Le read()
write()
close()
et shutdown()
appels, lorsqu'il est utilisé sur un socket, peut parfois soulever un ENOTCONN
erreur. Exactement ce que fait cette erreur signifie? Quelles sont les conditions qui permettraient de le déclencher? Je peux ne semblent jamais à reproduire localement, mais il y a des utilisateurs qui peuvent.
Droit maintenant, j'ai juste l'ignorer ENOTCONN
quand ils sont élevés par close()
et shutdown()
car il semble inoffensif, mais je ne suis pas entièrement sûr.
EDIT:
- Je suis absolument sûr que la
connect()
appel a réussi. J'ai vérifier sa valeur de retour. ENOTCONN
est le plus souvent soulevées parclose()
etshutdown()
. Je n'ai que très rarement vu uneread()
etwrite()
éleverENOTCONN
.
source d'informationauteur Hongli
Vous devez vous connecter pour publier un commentaire.
Si vous êtes sûr que rien de votre côté de la connexion TCP est la fermeture de la connexion, alors il me semble que la distance est la fermeture de la connexion.
ENOTCONN
comme d'autres l'ont souligné, signifie simplement que le socket n'est pas connecté. Cela ne veut pas nécessairement dire queconnect
a échoué. La prise peut très bien avoir été connecté auparavant, il n'était tout simplement pas au moment de l'appel qui a abouti àENOTCONN
.Ce qui diffère de l':
ECONNRESET
: l'autre extrémité de la connexion a envoyé un paquet TCP reset. Cela peut se produire si l'autre extrémité est de refuser une connexion, ou de ne pas reconnaître qu'il est déjà connecté, entre autres choses.ETIMEDOUT
: en général, cela s'applique uniquement auxconnect
. Cela peut se produire si la tentative de connexion n'est pas réussie au sein d'un système dépendant de la quantité de temps.EPIPE
peut parfois être retourné par certaines socket liés à des appels système dans des conditions qui sont plus ou moins les mêmes queENOTCONN
. Par exemple, sur certains systèmes,EPIPE
etENOTCONN
sont synonymes quand ils sont retournés parsend
.Alors qu'il n'est pas inhabituel pour
shutdown
de retourENOTCONN
puisque cette fonction est censé déchirure en bas de la connexion TCP, je serais surpris de voirclose
retourENOTCONN
. Il faut vraiment ne jamais le faire.Enfin, comme dwc mentionné,
EBADF
ne devrait pas s'appliquer dans votre scénario, à moins que vous tentez d'effectuer une opération sur un descripteur de fichier qui a déjà étéclose
d. Avoir un socket êtes déconnecté (c'est à dire la connexion TCP a cassé) n'est pas la même que la fermeture du descripteur de fichier associé à cette prise.Je crois ENOTCONN est retournée, en raison de l'arrêt() n'est pas censé revenir ECONNRESET ou d'autres plus précise des erreurs.
Il est faux de supposer que l'autre côté “juste” fermeture de la connexion. Sur le TCP-niveau, de l'autre côté à moitié fermer une connexion (ou annuler). La connexion est ordinaires, entièrement fermé si les deux parties en faire un shutdown() (ou close()). Si les deux côté faire, shutdown() réussit effectivement pour eux deux!
Le problème est que l'arrêt() ne pas réussir à l'ordinaire (demi-)fermeture de la connexion, ni le premier à le fermer, ni la deuxième. – Les erreurs figurant dans les normes POSIX docs pour l'arrêt(), ENOTCONN est le moins inappropriée, car les autres indiquent des problèmes avec les arguments passés à l'arrêt() (ou de ressources locales de problèmes à gérer la demande).
Donc ce qui s'est passé? Ces jours-ci, un périphérique NAT quelque part entre les deux parties pourrait avoir chuté l'association et l'envoi de paquets de RÉINITIALISATION comme une réaction. Réinitialiser les connexions sont si communs pour IPv4, qui vous permettra d'obtenir n'importe où dans votre code, même masqué comme ENOTCONN dans l'arrêt().
Un bug de codage pourrait être aussi la raison. Sur un socket non bloquant, par exemple, un connect() peut retourner 0 sans indiquant une connexion réussie encore.
C'est parce que, au moment de la fermeture() le support, vous avez des données dans la prise de tampon d'attente pour être livré à la partie à distance qui a fermé() ou referme son douille de réception.
Je n'ai pas fini de comprendre comment les sockets de travail, je suis un peu un noob, et je n'ai pas réussi à trouver, même les fichiers où ce "shutdown" de la fonction est mise en œuvre, mais, voyant qu'il n'y a pratiquement pas de manuel d'utilisation pour l'ensemble des sockets chose que j'ai commencé à essayer toutes les possibilités jusqu'à ce que j'ai obtenu l'erreur dans un environnement "contrôlé". Il pourrait être quelque chose d'autre, mais après beaucoup d'essayer ce sont les explications que j'ai réglé pour:
Point de terminaison de Transport n'est pas connecté
La socket est associée à un protocole orienté connexion et n'a pas été connecté. C'est généralement une programmation faille.
À partir de: http://www.wlug.org.nz/ENOTCONN
Si vous êtes sûr que vous avez correctement connecté en premier lieu,
ENOTCONN
est le plus susceptible d'être causé par lefd
être fermé sur votre fin (peut-être dans un autre thread?) pendant que vous êtes au milieu d'une demande, ou par la connexion de tomber pendant que vous êtes dans le milieu de la demande.Dans tous les cas, cela signifie que le socket n'est pas connecté. Aller de l'avant et de nettoyer cette prise. Il est mort. Pas de problème appelant
close()
oushutdown()
.