Quand un send () non-bloquant ne transfère que des données partielles, pouvons-nous supposer qu'il renvoie EWOULDBLOCK au prochain appel?
Deux cas, ils sont bien documentées dans les pages de manuel pour les sockets non bloquant:
- Si send() renvoie la même longueur que le tampon de transfert, l'ensemble du transfert terminé avec succès, et la prise peut ou peut ne pas être dans un état de retour EAGAIN/EWOULDBLOCK le prochain appel >0 octets à transférer.
- Si send() renvoie -1 et errno est EAGAIN/EWOULDBLOCK, aucun transfert fini, et le programme doit attendre jusqu'à ce que le support est prêt pour plus de données (EPOLLOUT dans le epoll cas).
Ce n'est pas documentée pour les sockets nonblocking est:
- Si send() renvoie une valeur positive plus petite que la taille de la mémoire tampon.
Est-il sûr de supposer que le send() serait de retour EAGAIN/EWOULDBLOCK même un octet de plus de données? Ou si un non-blocage de programme essayez d'envoyer() une fois de plus pour obtenir un concluante EAGAIN/EWOULDBLOCK? Je suis inquiet à propos de mettre un EPOLLOUT watcher sur la prise, si ce n'est pas vraiment dans un "bloquerait" état de répondre à sortir de.
Évidemment, la seconde stratégie (en essayant de nouveau pour obtenir quelque chose de concluant) a bien défini le comportement, mais c'est plus détaillé et met un coup sur la performance.
source d'informationauteur David Timothy Strauss | 2013-10-15
Vous devez vous connecter pour publier un commentaire.
Un appel à
envoyer
a trois résultats possibles:send
réussit et retourne le nombre d'octets accepté (éventuellement moins que vous l'avez demandé).send
.→si le socket est le blocage,
send
blocs→si la socket est non-bloquante,
send
échoue avecEWOULDBLOCK
/EAGAIN
send
échoue avec une erreurSi le nombre d'octets accepté par
send
est plus petit que le montant que vous avez demandé, alors cela signifie donc que le tampon d'envoi est maintenant complet. Cependant, c'est purement circonstancielle et non-faisant autorité à l'égard de toute les futurs appels àsend
.Les informations retournées par
send
est qu'un "instantané" de l'état actuel au moment où vous avez appelésend
. Par les tempssend
est retourné ou par le temps que vous appelezsend
encore une fois, cette information peut être dépassé. La carte réseau pourrait mettre un datagramme sur le fil alors que votre programme est à l'intérieur desend
, ou un ordre de la nanoseconde plus tard, ou à tout autre moment, -- il n'y a aucun moyen de savoir. Vous saurez quand le prochain appel réussit (ou quand ça ne marche pas).En d'autres termes, ce n' pas implique que le prochain appel à
send
sera de retourEWOULDBLOCK
/EAGAIN
(ou serait-bloc si la prise n'était pas non bloquant). Essayez jusqu'à ce que vous avez appelé "l'obtention d'un concluanteEWOULDBLOCK
" est la bonne chose à faire.Pas. Le support reste dans la mode: dans ce cas, la non-mode de blocage, a assumé en dessous de tout.
Jusqu'à ce que le buffer n'est pas complète. Le support reste en mode sans blocage.
Il n'y a seulement que beaucoup de place dans le support du tampon d'envoi.
Il n'est pas " sûr "pour" d'assumer [il] serait bloc". Il ne sera pas. C'est en mode sans blocage. EWOULDBLOCK signifie qu'il aurait bloqué en mode de blocage.
Qui est à vous. L'API travaille selon ce que vous décidez.
Il n'est pas "blocage". Il n'est pas de blocage sur quoi que ce soit. C'est en mode sans blocage. Le tampon d'envoi s'est rempli à cet instant. Il pourrait être complètement vide un instant plus tard.
Je ne vois pas ce que vous êtes inquiet au sujet de. Si vous avez des données en attente et la dernière écriture de ne pas envoyer tout cela, sélectionnez pour writability, et d'écrire quand vous l'obtenez. Si une telle écriture envoie tout, ne sélectionnez pas pour writability la prochaine fois.
Sockets sont généralement accessible en écriture, à moins de leur envoyer de la mémoire tampon est pleine, afin de ne pas les sélectionner pour writability tout le temps, comme vous venez de le faire un tour de boucle.