2009-07-08 4 views
12

Je travaille sur l'écriture d'une application réseau en C++ sur la plate-forme Linux en utilisant l'API sockets typique, et j'examine deux façons d'écrire un tableau d'octets vers un flux TCP: soit en appelant write(), soit en appelant send(). Je sais que, puisque c'est Linux, le handle de socket est simplement un descripteur de fichier, et donc il est valide d'effectuer des appels read() et write() sur le socket, cependant l'API sockets fournit aussi send() et recv () fonctionne pour effectuer les mêmes tâches. Je me demande donc s'il y a une raison particulière de choisir une classe de fonctions par rapport à l'autre - les fonctions d'envoi/de recueil sont-elles optimisées pour l'écriture/lecture en réseau, sont-elles plus performantes, etc. Ou est-ce vraiment arbitraire quelles fonctions j'utilise? Est-ce que read() et write() se comportent correctement dans tous les cas?Impact de l'utilisation de write() au lieu de send() lors de l'écriture sur un socket

Merci pour toute idée!

Répondre

19

Il ne devrait pas y avoir de différence. Je cite man 2 send:

La seule différence entre send() et write() est la présence de drapeaux. Avec le paramètre zero flags, send() est équivalent à write().

Tant que vous ne voulez pas spécifier et drapeaux pour send() vous pouvez utiliser write() librement.

+0

Est-ce vrai aussi pour FreeBSD ou d'autres plateformes? - Cette ligne n'apparaît pas dans ma page de manuel send (2). –

+0

@ GoodPerson Cela s'applique à toutes les plateformes. Si ce n'était pas le cas, 'inetd' et autres ne fonctionneraient pas. ('inetd' utilise votre socket dans le stdin et le stdout de votre processus de démon, et votre processus peut interagir directement avec stdin et stdout de la manière habituelle, sans se rendre compte qu'il s'agit de sockets. –

6

recv et send vous permettent de spécifier des indicateurs, comme pour les paquets hors bande. Si vous n'avez pas besoin de spécifier les drapeaux, read et write sont parfaitement adéquats.

1

write v.s. send pour un seul octet, ou un seul tableau ne sera probablement pas très différent - ils vont bientôt finir par le même chemin de code (en fin de compte, ils effectuent la même opération). Les frais généraux de transmission en réseau sont très peu susceptibles d'être à ce niveau; ce sera la connexion TCP réelle et le déplacement des bits sur les fils.

Toutefois, si vous avez l'intention d'envoyer de grands messages en plusieurs parties en une seule fois, vous devriez consulter le syscall sendmsg() - cela vous permet de spécifier une liste de tableaux de données non contigus à envoyer. À la fin de la journée, suivez les recommandations habituelles: écrivez d'abord l'application, puis comparez les points de repère pour voir où se trouvent vos goulots d'étranglement.

+1

Sur les tableaux non contigus à recevoir/envoyer: readv et writev permettent également cela. Yay pour disperser/rassembler I/O! –

Questions connexes