266 votes

Quelle est la différence entre read() et recv() , et entre send() et write() ?

Quelle est la différence entre read() y recv() et entre send() y write() dans la programmation de socket en termes de performances, de vitesse et d'autres comportements ?

6 votes

Pensez à l'écriture comme mise en œuvre comme ceci : #define write(...) send(##__VA_ARGS__, 0) .

175voto

Gonzalo Points 11758

La différence est que recv() / send() travaillent uniquement sur les descripteurs de socket et vous permettent de spécifier certaines options pour l'opération réelle. Ces fonctions sont légèrement plus spécialisées (par exemple, vous pouvez définir un indicateur pour ignorer SIGPIPE ou pour envoyer des messages hors bande...).

Fonctions read() / write() sont les universel fonctions de descripteurs de fichiers fonctionnant sur tous les descripteurs.

10 votes

C'est incorrect, il y a une autre différence dans le cas de datagrammes de longueur 0 - Si un datagramme de longueur zéro est en attente, read(2) et recv() avec un argument flags de zéro fournissent un comportement différent. Dans cette circonstance, read(2) n'a aucun effet (le datagramme reste en attente), alors que recv() consomme le datagramme en attente.

2 votes

@AbhinavGauniyal Comment cela pourrait-il fournir comportement différent ? S'il y a un datagramme de 0 octet, les deux, recv y read ne fournira aucune donnée à l'appelant mais également aucune erreur. Pour l'appelant, le comportement est le même. L'appelant peut même ne rien savoir des datagrammes (il peut ne pas savoir qu'il s'agit d'une socket et non d'un fichier, il peut ne pas savoir qu'il s'agit d'une socket de datagramme et non d'une socket de flux). Le fait que le datagramme reste en attente est une connaissance implicite de la façon dont les piles IP fonctionnent dans les noyaux et n'est pas visible pour l'appelant. Du point de vue de l'appelant, ils fourniront toujours le même comportement.

2 votes

@Mecki ce n'est pas une connaissance implicite pour tout le monde, prenez moi par exemple :)

105voto

Jonathan Feinberg Points 24791

Par le premier résultat sur Google

read() est équivalent à recv() avec un paramètre flags de 0. D'autres valeurs pour le paramètre flags changent le comportement de recv(). De même, write() est équivalent à send() avec flags == 0.

38 votes

Ce n'est pas toute l'histoire. recv ne peut être utilisé que sur une socket, et produira une erreur si vous essayez de l'utiliser sur, disons, STDIN_FILENO .

107 votes

Ce fil de discussion est maintenant le premier résultat sur Google, Google adore stackoverflow.

19voto

Bastien Léonard Points 18404

read() y write() sont plus génériques, ils fonctionnent avec n'importe quel descripteur de fichier. Cependant, ils ne fonctionnent pas sous Windows.

Vous pouvez passer des options supplémentaires à send() y recv() Il se peut donc que vous deviez les utiliser dans certains cas.

8voto

ajb Points 11197

J'ai remarqué récemment que lorsque j'utilisais write() sur une socket sous Windows, cela fonctionne presque (le FD passé à write() n'est pas la même que celle passée à send() ; j'ai utilisé _open_osfhandle() pour obtenir le FD à passer à write() ). Cependant, cela n'a pas fonctionné lorsque j'ai essayé d'envoyer des données binaires comprenant le caractère 10. write() quelque part, j'ai inséré le caractère 13 avant celui-ci. En le changeant en send() avec un paramètre flags de 0 a réglé ce problème. read() pourrait avoir le problème inverse si 13-10 sont consécutifs dans les données binaires, mais je ne l'ai pas testé. Mais cela semble être une autre différence possible entre send() y write() .

4 votes

0 votes

Windows ne reçoit pas non plus de paquet UDP avec moins de 3 octets de données, donc, il y a des problèmes avec Windows :)

3voto

unwind Points 181987

"Performance et vitesse" ? Ce ne sont pas des sortes de ... synonymes, ici ?

Quoi qu'il en soit, le recv() L'appel prend les drapeaux que read() ne le fait pas, ce qui le rend plus puissant, ou du moins plus pratique. C'est une différence. Je ne pense pas qu'il y ait une différence de performance significative, mais je ne l'ai pas testée.

17 votes

Le fait de ne pas avoir à s'occuper des drapeaux peut être perçu comme plus pratique.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X