C, sendfile () et send () différence?
sendfile() copie les données entre les deux fichier descripters dans l'espace du noyau. Quelque part, j'ai vu que si vous écrivez un serveur web en C sous linux, vous devez utiliser send() et recv() au lieu d'utiliser write() et read(). Alors, le send() utiliser le noyau de l'espace?
Ce que je utiliser pour l'envoi d' - sendfile() ou envoyez - () - sur le côté client, je vais utiliser les recv() à droite?
Sur le revers de la médaille, page de man dit: "La seule différence entre send() et write(2) est la présence de drapeaux. Avec un zéro argument flags, send() est équivalent à écrire(2)."
source d'informationauteur KillBill
Vous devez vous connecter pour publier un commentaire.
Si
fd
est un socket descripteur de fichier, puis ces appels système sont identiques:send(fd, data, length, 0)
est le même quewrite(fd, data, length)
recv(fd, data, length, 0)
est le même queread(fd, data, length)
Donc, sauf si vous avez besoin de définir un non-zéro
flags
paramètre, il ne fait aucune différence si vous utilisezsend/recv
ouwrite/read
.La
sendfile
appel système est d'une optimisation. Si vous avez un socketsockfd
et d'un fichier régulierfilefd
et vous souhaitez copier un fichier de données à la prise (par exemple, si vous êtes un serveur web de servir un fichier), vous pouvez l'écrire comme ceci:Cependant, c'est inefficace: il s'agit du noyau de copier le fichier de données dans l'espace utilisateur (dans le
read
appel), puis de copier les mêmes données dans l'espace du noyau (dans lesend
appel).La
sendfile
appel système nous permet de passer tous les de que de copier et d'avoir le noyau de lire directement le fichier de données et de les envoyer sur le support d'un seul coup:Comme vous l'avez souligné, la seule différence est les drapeaux. send/recv sont pour la mise en réseau, alors que la lecture/écriture sont en général des fonctions d'e/S pour n'importe quel descripteur de fichier. envoyer n'est utile que vs écrivez lorsque vous souhaitez utiliser un drapeau, depuis que les indicateurs sont tous relatifs au réseau, il n'est pas logique d'appel d'envoyer sur un réseau non descripteur de fichier (je ne suis pas sûr de savoir si c'est encore valable).
Aussi vous devriez noter:
Ce qui signifie que vous ne pouvez pas copier à partir d'une prise (vous pouvez copier sur un support et avant 2.6.33 vous devez copier à un socket).
send
est spécifié par la norme POSIXqui dit:sendfile
est spécifique à Linux. Il indique au noyau de faire zéro-copie I/O à partir d'un fichier à un socket. (Notez que cela ne fonctionne que lorsque la source fd est un fichier et la destination est une prise de courant; pour le générique, spécifique à Linux, zéro-copie I/O, lire à ce sujetsplice()
.)Noter qu'il est rarement besoin d'utiliser spécifique à Linux, zéro-copie I/O. Le standard et portable
read
+write
(ousend
) boucle avec un petit tampon de l'espace utilisateur (8K 16K) sera généralement garder la mémoire tampon dans le cache L1, ce qui équivaut à "zéro" copie de la RAM du système du point de vue.Donc, à moins que votre profilage montre une différence pour votre application particulière, s'en tenir à des interfaces standard. Juste MUTUELLES.