10
votes

RECV avec msg_nonblock et msg_waittall

Je veux utiliser recv syscall avec des drapeaux non bloquants msg_nonblock. Mais avec ce drapeau SysCall peut revenir avant que la demande complète ne soit satisfaite. Donc,

  • Puis-je ajouter msg_waittall Drapeau? Sera-ce non bloqué?
  • ou comment dois-je réécrire le blocage de RECV dans la boucle avec NEBLOCKING RECV

1 commentaires

Je suppose que vous souhaitez épargner la mémoire de processus utilisateur (pour tamponner le message incomplet), vous souhaitez donc utiliser la mémoire de noyau. Je doute que cela fonctionnerait.


3 Réponses :


3
votes

EDIT:

La CRÉCLI UNILE () RETOURITE WHOIT est dans la mémoire tampon TCP au moment de l'appel au nombre requis d'octets. Msg_dontwait n'évite que le blocage s'il n'ya pas de données prêts à être lus sur la prise. Msg_waitall demande le blocage jusqu'à ce que l'ensemble du nombre d'octets demandés puisse être lu. Donc, vous ne recevrez pas de comportement "tout ou aucun". Au mieux, vous devriez obtenir de l'aigité si aucune donnée n'est présente et bloque que le message complet est disponible sinon.

Vous pourriez être capable de façonner quelque chose à partir de msg_peek ou d'IOCTL () avec une FIONREAD (si votre système le supporte) qui se comporte efficacement comme vous le souhaitez, mais je ne suis pas conscience de la manière dont vous pouvez accomplir votre objectif en utilisant les drapeaux RECV () .


1 commentaires

NONBLOCK peut revenir avec une seule partie du message requis. Je tiens à obtenir une formulaire eagain non bloquant RECV, s'il veut seulement retourner une partie de MSG. Donc, je veux un comportement non bloqué avec "tout ou rien"



3
votes

C'est ce que j'ai fait pour le même problème, mais je voudrais une certaine confirmation que cela fonctionne comme prévu ... XXX


0 commentaires

4
votes

pour IPv4 TCP reçoit sur Linux au moins sur Linux, msg_waittall est ignoré si Msg_nonblock est spécifié (ou le descripteur de fichier est défini sur non bloquant).

de tcp_recvmsg () dans net / IPv4 / TCP.c.C dans le Linux Kernel: P>

if (copied >= target && !sk->sk_backlog.tail)
        break;

if (copied) {
        if (sk->sk_err ||
            sk->sk_state == TCP_CLOSE ||
            (sk->sk_shutdown & RCV_SHUTDOWN) ||
            !timeo ||
            signal_pending(current))
                break;


1 commentaires

Sûrement Timeo Être zéro signifie simplement qu'il n'y a pas de délai de lecture?