8
votes

Quel est le but de l'option SOCK SO_SNDLOWAT

Je porte actuellement un logiciel en C de TRU64 à Linux SUSE 11. Sur Tru64, ils définissent la valeur de SO_SNDLOWAT SOCKET OPTION sur 1024 * 64 . Sur Linux, cette option n'est pas changeante et sa valeur est 1.

Je veux comprendre, quel sera l'impact de ne pas définir so_sndlowat à 1024 * 64 sur l'exécution du logiciel sur Linux.

Le problème est que j'ai trouvé deux définitions (interprétations) du but de so_sndlowat :

  1. trouvé sur la page man de socket sur Linux:

    SO_SNDLOWAT
    Spécifiez le nombre minimum d'octets dans le tampon jusqu'à ce que le La couche de socket passera les données au protocole

    J'ai compris qu'il spécifie le nombre minimum d'octets dans le tampon pour procéder (dans ce cas pour envoyer le message). Le tampon doit être rempli au moins pour SO_SNDLOWAT BYTES pour continuer

  2. trouvé dans le livre " Programmation de réseau UNIX: Les sockets API de réseautage de W. Richard Stevens, Bill Fenner, Andrew M. Rudoff " "

    La marque d'envoi à faible teneur en eau est la quantité d'espace disponible qui doit exister dans le tampon d'envoi de socket pour que vous puissiez sélectionner "Entreprise".

    J'ai compris que, si je veux écrire dans le tampon de socket (peu importe la taille de ce que j'écris), le tampon doit avoir au moins SO_SNDLOWAT BYTES GRATUIT.

    Je ne sais pas quoi faire de so_sndlowat .


0 commentaires

3 Réponses :


1
votes

La première description est l'interprétation correcte.

Quant à l'impact de ne pas pouvoir définir SO_SNDLOWAT , je ne pense pas que cela importerait, car la performance dépend des choses comme l'algorithme de Nagle, la découverte de la Path-MTU, etc. Je soupçonne que D'autres implémentations TCP / IP ignorent silencieusement cette option.


2 commentaires

Avoir la deuxième fonctionnalité a du sens dans la cas "Liste liée" également: si Sélectionnez demande si une prise est écrite, le noyau doit allouer un tampon à ce stade et ne revenir à l'application que si elle pourrait . Je peux voir le mérite de demander une garantie que envoyer peut accepter au moins n octets.


Ils sont à la fois correct .



1
votes

afaik le second est le bon, mais je n'ai jamais été capable de l'utiliser.

SO_SNDLOWAT n'est pas modifiable sous Linux. setSockopt échoue avec le Erreur Enoprotoopt


2 commentaires

Tcp_notsent_lowat a été introduit dans le noyau 2.12.


@Matt Vous avez une erreur tcp_notsent_lowat avec so_sndlowat



3
votes

Comme vous pouvez le voir à cette question , qui couvre d'autres options de prise, la réponse dépend du système d'exploitation, de sorte que les deux Les réponses peuvent être correctes, car on est une réponse du monde Linux et une réponse du monde UNIX (BSD et CO).

dans les clones BSD et BSD, cette option signifie ce qui suit:

  1. Si la prise est non bloquante et que vous appelez envoyer () , il doit être en mesure d'accepter toutes les données fournies à la fois ou accepter au moins so_sndlowat octets de données; Si cela n'est pas possible, cela n'acceptera aucune donnée et envoyer () échoue avec une erreur.

    Donc, si vous définissez SO_SNDLOWAT à 100 et essayez d'envoyer 50 octets, il enverra 50 octets ou rien. Si vous définissez SO_SNDLOWAT à 100 et essayez d'envoyer 200 octets, il doit au moins accepter 100 octets de données, il peut accepter davantage, jusqu'à 200 octets, ainsi que toute valeur comprise entre 100 et 200, juste au moins 100. N'oubliez pas que la valeur par défaut de SO_SNDLOWAT est 1 et c'est aussi le comportement par défaut d'une prise non bloquante (il doit accepter au moins 1 octet ou échouer avec < code> ewouldblock )

    Notez que les sockets UDP sont toujours tout-ou--rien, ils n'acceptent jamais uniquement "une partie des données", définissant ainsi SO_SNDLOWAT est uniquement pertinent pour les sockets TCP, qui peuvent accepter uniquement une partie des données offertes.

  2. Si la prise est bloquée, réglage SO_SNDLOWAT n'a aucun effet réel sur l'appel envoi () , comme dans ce cas, la prise accepte toujours toutes les données Ou il bloquera et ensuite il bloquera jusqu'à ce que toutes les données aient été acceptées ou que le délai d'attente d'envoi est touché (si un délai d'attente d'envoi a été défini avec SO_SNDTimeo ou le protocole sous-jacent a un délai d'attente propre pour l'envoi).

  3. Peu importe si la prise bloque ou non, peu importe si elle est UDP ou TCP, un sondage () ou SELECT () L'appel ne prétend que Cette prise est écoute, si au moins SO_SNDLOWAT peut être accepté par un envoyer () appel.

    Alors qu'est-ce que cette option est vraiment bonne? Habituellement, il est utilisé pour éviter que votre processus alimente les données en octet-for-octet une fois que le tampon de socket a fonctionné intégralement, mais en gros morceaux, comme avec un comportement par défaut, Sélectionnez () et sondage () < / Code> dira que la prise est écritable, même s'il n'y a qu'une place pour un seul octet dans le tampon de prise. En d'autres termes, il s'agit simplement d'une optimisation de la performance, car le code qui fonctionne correctement avec des écrivies de prise arbitraire fonctionnera correctement, si SO_SNDLOWAT est défini et quelle que soit la valeur, il peut simplement nécessiter beaucoup moins de temps de processeur Certaines situations extrêmes si so_sndlowat a une valeur raisonnable. Mais comme avec tous les médicaments de performance, si vous ne savez pas exactement ce que vous faites, vous pouvez facilement rendre les choses bien pire en définissant les mauvaises valeurs, donc en cas de doute, ne touchez pas ce réglage.


0 commentaires