8
votes

Pourquoi ne peut-il pas bloquer jusqu'à ce qu'il reçoive toutes les données?

Pourquoi le système RECV est-il simplement bloquer jusqu'à ce que toutes les données soient reçues? Chaque fois que j'ai vu un appel recv , c'est dans une boucle tandis que cela ne cesse de continuer à appeler recv jusqu'à ce que toutes les données soient là. Pourquoi pas seulement avoir recv bloc en premier lieu?


0 commentaires

3 Réponses :


9
votes

Vous pouvez demander à ce bloc Recv jusqu'à ce que toutes les données soient reçues, avec le drapeau msg_waittall . Toutefois, si un signal arrive, un appel système qui a effectué certains travaux (c.-à-d. Une partie de la réception des données) ne peut pas être redémarré pour recevoir le reste. En tant que tel, même avec msg_waitall , il existe des cas où l'appel RECV peut renvoyer avant que le tampon soit plein et que vous devez être prêt à gérer ces cas. Compte tenu de cela, beaucoup de gens choisissent simplement de boucler et de ne pas vous embêter avec des drapeaux peu connus tels que msg_waitall .

Quant à la raison pour laquelle c'est le cas par défaut, il y a quelques raisons qui me viennent à l'esprit:

  • fréquemment vous veux recevoir des lectures partielles. Par exemple, si vous affichez incrémentalement les données telles qu'elles entrent, ou si vous le spécifiez ailleurs, ou si les données sont simplement si grandes, vous ne pouvez plus tamponner toute la mémoire en mémoire. Après tout, si vous écrivez simplement immédiatement à un fichier, vous souciez-vous de la diviser dans 200 écrit au lieu de, disons, 150?
  • Parfois, vous ne savez même pas combien de données dont vous avez besoin au début. Considérez le protocole telnet , qui était populaire à l'heure où la BSD Sockets API a été conçue. Vous recevrez généralement une poignée d'octets à la fois, il n'y a pas de champs de longueur vous indiquant la quantité de données à attendre, et de plus vous devez afficher ces données tout de suite . Il n'a pas de sens à bloquer tant que vous remplissez un tampon ici. De même avec les protocoles orientés en ligne tels que SMTP ou IMAP - vous ne savez pas combien de temps la commande est jusqu'à ce que vous ayez reçu tout cela.
  • RECV est souvent utilisé pour les sockets de datagramme, où il reçoit un seul datagramme, même s'il est beaucoup plus petit que le tampon fourni. L'extension naturelle de streaming des prises est de revenir autant que possible sans attendre.

    Mais surtout, puisque vous devez être prêt à faire face à un tampon partiel de toute façon , il est bon de forcer les gens à y faire face par défaut, alors ils augmentent les bugs dans leur boucle - plutôt que de les faire rester cacher jusqu'à ce qu'un signal arrive à un moment malheureux.


0 commentaires

4
votes

Dans la plupart des cas, vous ne savez pas combien de données est "toutes les données". Par exemple, si vous recevez des données dans un protocole orienté ligne, une ligne peut être de 10 octets longue ou 65 octets longs.


0 commentaires

2
votes

Vous pouvez modifier des drapeaux de prise en blocage ou sans blocage. Votre cas spécifique n'a rien à voir avec le blocage ou ne pas bloquer.

Il ne ferait aucun sens de faire fonctionner une fonction de réseau de la manière dont vous décrivez par défaut - Et si le flux ne finit jamais .. Si le programme ne se termine jamais? Prima Facia, cela ne semble pas comme sain défaut comportement.

lire http://www.scottklement.com/rpg/socktt/nonblocking.html pour vous familiariser avec le blocage et l'IO non bloquantes.


0 commentaires