IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Réseau C Discussion :

Sur un socket : send et recv ou read et write ? [Débat]


Sujet :

Réseau C

  1. #21
    Membre émérite Avatar de nicolas.sitbon
    Profil pro
    Inscrit en
    Août 2007
    Messages
    2 015
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 2 015
    Points : 2 280
    Points
    2 280
    Par défaut
    Merci pour l'info en tout cas.

  2. #22
    Expert éminent
    Avatar de Melem
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Janvier 2006
    Messages
    3 656
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Janvier 2006
    Messages : 3 656
    Points : 8 389
    Points
    8 389
    Par défaut
    Pour participer un peu au débat, et pour faire une sorte de synthèse (ou de résumé) :

    - send et recv ont des arguments en plus par rapport à read et write. C'est clair qu'ils sont plus adaptés au sockets et permettent des choses que read et write ne permettent pas.

    - send et recv sont utilisables sur un socket sous les systèmes respectant la norme POSIX comme sous certains systèmes qui ne la respectent pas (un exemple bien connu : Windows). read et write sont utilisables sur un socket que sous les systèmes qui respectent la norme POSIX (en pratique : UNIX et ses clones). La encore, je trouve donc plus intéressant d'utiliser send et recv plutôt que read et write sur uns ocket.

    - Sur un système respectant la norme POSIX, read et write, qui sont les fonctions d'E/S de plus bas niveau au niveau de l'API, peuvent être utilisées sur tout ce qui peut être lu ou écrit (fichier, tube, socket, mémoire, etc.). send et recv, POSIX ou pas POSIX, ne peuvent être utilisées que sur un socket. Lorsqu'on veut avoir du code générique pour un système POSIX, il faut donc en effet utiliser read et write.

    En ce qui concerne les sockets sous Windows, Microsoft dit clairement qu'un handle de socket n'est pas forcément un handle de fichier. Il n'est donc pas garanti qu'on peut utiliser _open_osfhandle sur un socket dans le but de pouvoir utiliser les fonctions _read et _write.

  3. #23
    Membre éprouvé Avatar de orfix
    Homme Profil pro
    Inscrit en
    Avril 2007
    Messages
    707
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Maroc

    Informations professionnelles :
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Avril 2007
    Messages : 707
    Points : 1 132
    Points
    1 132
    Par défaut Je découvre la programmation réseaux et les sockets
    Je pense qu'hormis le fait que le système soit POSIX ou pas les fonctions revc/send ont un paramètre en plus contrairement à read/write, ce dernier d'après ce que j'ai compris est souvent mis à zéro, donc j'aurais tendance à utiliser read/write et réserver recv/send pour les usages nécessitant ce fameux paramètres, pour la portabilité j'ajoute ceci:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    #ifdef _WIN32
    #	define write(fd, buf, len)	send(fd, buf, len, 0)
    #	define read(fd, buf, len)	recv(fd, buf, len, 0)
    #endif /* _WIN32 */

  4. #24
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par ssmario2 Voir le message
    Je pense qu'hormis le fait que le système soit POSIX ou pas les fonctions revc/send ont un paramètre en plus contrairement à read/write, ce dernier d'après ce que j'ai compris est souvent mis à zéro, donc j'aurais tendance à utiliser read/write et réserver recv/send pour les usages nécessitant ce fameux paramètres, pour la portabilité j'ajoute ceci:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    #ifdef _WIN32
    #	define write(fd, buf, len)	send(fd, buf, len, 0)
    #	define read(fd, buf, len)	recv(fd, buf, len, 0)
    #endif /* _WIN32 */
    C'est une complication inutile. Autant utiliser send() / recv() partout... Pour une fois que c'est portable ...

  5. #25
    Expert éminent
    Avatar de Melem
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Janvier 2006
    Messages
    3 656
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Janvier 2006
    Messages : 3 656
    Points : 8 389
    Points
    8 389
    Par défaut
    les fonctions revc/send ont un paramètre en plus contrairement à read/write, ce dernier d'après ce que j'ai compris est souvent mis à zéro, donc j'aurais tendance à utiliser read/write et réserver recv/send pour les usages nécessitant ce fameux paramètres
    En ce qui concerne le dernier paramètre souvent mis à 0, c'est vrai pour send(). Pour recv, Le flag MSG_PEEK est au moins aussi utilisé que 0. Enfin, faire usage des deux en même temps c'est pire qu'utiliser des fonctions non portables, non génériques, mais homogènes (les WSASend/WSARecv par exemple).

  6. #26
    Expert confirmé
    Homme Profil pro
    Inscrit en
    Septembre 2006
    Messages
    2 957
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Septembre 2006
    Messages : 2 957
    Points : 4 386
    Points
    4 386
    Par défaut
    est-on certain que "derrière le rideau" read/write n'appelent pas recv/send quand le fd est un socket ?

    (sous autre chose que Windows… évidemment…)

  7. #27
    Expert éminent
    Avatar de Melem
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Janvier 2006
    Messages
    3 656
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Janvier 2006
    Messages : 3 656
    Points : 8 389
    Points
    8 389
    Par défaut
    Oui. read et write ce sont les fonctions d'E/S de plus bas niveau de l'API UNIX. Toutes les autres fonctions d'E/S (celles de la lib standard, celles de l'API Socket, etc.) y font appel (ou devraient pouvoir être implémentés en y faisant appel).

  8. #28
    Expert confirmé
    Homme Profil pro
    Inscrit en
    Septembre 2006
    Messages
    2 957
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Septembre 2006
    Messages : 2 957
    Points : 4 386
    Points
    4 386
    Par défaut
    Citation Envoyé par Melem Voir le message
    Oui. read et write ce sont les fonctions d'E/S de plus bas niveau de l'API UNIX. Toutes les autres fonctions d'E/S (celles de la lib standard, celles de l'API Socket, etc.) y font appel (ou devraient pouvoir être implémentés en y faisant appel).
    tel que vous exprimez les choses, cela sous-entendrait que recv/send appellent read/write… ou autrement dit qu'une fonction spécialisée sur les sockets appelle une fonction générale qui prend n'importe quel type de FD…

    ce qui laisse planer un sérieux doute…

    en fait recv/send appellent directement recvfrom/sendto qui sont aussi des syscall tout comme read/write…

  9. #29
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par JeitEmgie Voir le message
    en fait recv/send appellent directement recvfrom/sendto qui sont aussi des syscall tout comme read/write…
    J'ai de gros doutes là dessus.

    Je ne vois pas à quoi servent toutes ces élucubrations. Les fonctions pour écrire et lire sur les sockets sont send() et recv() en mode connecté. Point. Il n'y a pas à tergiverser.

  10. #30
    Expert éminent
    Avatar de Melem
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Janvier 2006
    Messages
    3 656
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Janvier 2006
    Messages : 3 656
    Points : 8 389
    Points
    8 389
    Par défaut
    Citation Envoyé par JeitEmgie Voir le message
    tel que vous exprimez les choses, cela sous-entendrait que recv/send appellent read/write… ou autrement dit qu'une fonction spécialisée sur les sockets appelle une fonction générale qui prend n'importe quel type de FD…

    ce qui laisse planer un sérieux doute…

    en fait recv/send appellent directement recvfrom/sendto qui sont aussi des syscall tout comme read/write…
    Tu n'as pas compris. read et write, je rappelle, ce sont les fonctions d'E/S génériques de plus bas niveau du système (UNIX). Elles ne font que lire/écrire des octets de manière la plus directe qui existe depuis/sur le fichier (qui peut être un fichier sur disque, un périphérique, un tube, un socket, etc.). send et recv ont un paramètre en plus par rapport à read et write ce qui prouve qu'elles sont de plus haut niveau et éventuellement utilisables que sur un type particulier de fichier (ici : les sockets seulement). Pour comprendre le lien qu'il y a entre send/recv et read/write sous UNIX, supposons un peu que write soit implémentée comme ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    int write(int fd, const void * buf, size_t count)
    {
        /* vars ... */
     
        switch(__file_type(fd))
        {
        case __DISK_FILE:
            __disk_file_write(fd, buf, count);
            break;
        case __SOCKET:
            __socket_write(fd, buf, count);
            break;
        /* etc. */
        }
     
        /* return */
    }
    En général, send utilise tout simplement write mais qu'est-ce qui empêchera un autre implémenteur d'utiliser directement __socket_write par exemple ?

  11. #31
    Expert confirmé
    Homme Profil pro
    Inscrit en
    Septembre 2006
    Messages
    2 957
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Septembre 2006
    Messages : 2 957
    Points : 4 386
    Points
    4 386
    Par défaut
    Citation Envoyé par Melem Voir le message
    Tu n'as pas compris. read et write, je rappelle, ce sont les fonctions d'E/S génériques de plus bas niveau du système (UNIX). Elles ne font que lire/écrire des octets de manière la plus directe qui existe depuis/sur le fichier (qui peut être un fichier sur disque, un périphérique, un tube, un socket, etc.). send et recv ont un paramètre en plus par rapport à read et write ce qui prouve qu'elles sont de plus haut niveau et éventuellement utilisables que sur un type particulier de fichier (ici : les sockets seulement). Pour comprendre le lien qu'il y a entre send/recv et read/write sous UNIX, supposons un peu que write soit implémentée comme ceci :

    En général, send utilise tout simplement write mais qu'est-ce qui empêchera un autre implémenteur d'utiliser directement __socket_write par exemple ?
    j'ai très bien compris et je ne suppose rien du tout, ci-dessous exemple de code source d'un Unix que j'ai ici sous la main :

    recv.c
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    ssize_t
    recv(s, buf, len, flags)
    	int s, flags;
    	size_t len;
    	void *buf;
    {
    	return (_recvfrom(s, buf, len, flags, NULL, 0));
    }
    recvfrom.s
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    SYSCALL(recvfrom, 6)
    ici read/write et recvfrom/sendto sont des SYSCALL, recv/send sont des glues.
    mais que tous les U*x ne fassent pas exactement de la même façon… c'est plus que probable…

    Une implémentation où recv/send appellent directement read/write… : le code source please !
    appeler la même sous-fonction (votre _socket_XXX) qui traite le cas du socket : oui c'est plausible…
    appeler read/write qui doivent tester le type de FD alors qu'on le connaît déjà : çà mérite un (très) gros "?" …

  12. #32
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 381
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 381
    Points : 41 582
    Points
    41 582
    Par défaut
    Citation Envoyé par Melem Voir le message
    send et recv ont un paramètre en plus par rapport à read et write ce qui prouve qu'elles sont de plus haut niveau
    Là, il faudra m'expliquer ton raisonnement, car d'habitude c'est le contraire.

    Exemple: NtCreateFile vs. CreateFile vs. _open vs. fopen.

  13. #33
    Expert éminent
    Avatar de Melem
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Janvier 2006
    Messages
    3 656
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Janvier 2006
    Messages : 3 656
    Points : 8 389
    Points
    8 389
    Par défaut
    Tu argumentes en te basant sur un cas particulier. Et j'appellerai ça toujours cas particulier même s'il y a des centaines d'UNIX qui le font. D'après ton code, recvfrom est donc tout simplement le __socket_read du système mais rien n'oblige les autres systèmes à en faire autant. Donc ici, effectivement, read appelle recvfrom lorsque fd est un socket, parce qu'on est dans un cas particulier où __socket_read == recvfrom.

    Une implémentation où recv/send appellent directement read/write… : le code source please !
    Je t'en fais une ? Non franchement, un code source ne prouvera rien. C'est juste performances vs simplicité de codage et c'est peut-être performances qui est la plus souvent privilégiée contrairement à ce que je pensais mais bref, le fait est qu'on a read/write qui sont génériques mais sous POSIX seulement et send/recv qui sont portables et mieux adaptés aux sockets mais qui ne marchent que sur des sockets. Les implémentations, ça change d'un système à un autre.

  14. #34
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 381
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 381
    Points : 41 582
    Points
    41 582
    Par défaut
    Le problème est pourtant simple: Si recv() appelle read(), comment le flag MSG_PEEK est-il interprété?

  15. #35
    Expert éminent
    Avatar de Melem
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Janvier 2006
    Messages
    3 656
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Janvier 2006
    Messages : 3 656
    Points : 8 389
    Points
    8 389
    Par défaut
    Chui bête en effet. J'étais tellement convaincu qu'il n'y avait pas plus bas niveau que read/write que je ne réfléchissais plus avant de poster. Mes excuses à JeitEmgie. Pas étonnant que MS ont décidé de ne pas mêler sockets et file handles ensemble.

  16. #36
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 381
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 381
    Points : 41 582
    Points
    41 582
    Par défaut
    Petit remontage de thread pour les dernières trouvailles: Au moins, il est possible, sous Windows, de savoir si un HANDLE donné est un fichier/pipe ou un socket:
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    BOOL IsSocket(HANDLE h)
    {
    	SOCKADDR sa;
    	int len = sizeof sa;
    	if(getsockname((SOCKET)h, &sa, &len)==SOCKET_ERROR)
    	{
    		//It failed: Is it because h is not a socket, or because it's not bound?
    		if(GetLastError()==WSAEINVAL)
    			return TRUE;
    		else
    			return FALSE; //For all other errors, assume it's not a socket.
    	}
    	else
    		return TRUE; //Success! it's a socket.
    }
    Cela marchera sans problème, vu que les sockets restent quand même des handles particuliers (GetFileType() marche dessus, retournant FILE_TYPE_PIPE) et qu'il n'y a donc pas de collisions possibles.

    Par contre, je ne vois aucun moyen de vérifier à 100% si un int est un socket ou un descripteur. Toutefois, si l'on prend le réflexe d'utiliser _open_osfhandle() sur les sockets, on peut toujours utiliser la fonction _get_osfhandle sur le descripteur obtenu pour tester le handle et savoir s'il pointe vers un fichier/pipe ou un socket... (bien qu'on ait toujours des problèmes lors de la fermeture, problèmes qui peuvent être contournés dans une application mono-threadée).

+ Répondre à la discussion
Cette discussion est résolue.
Page 2 sur 2 PremièrePremière 12

Discussions similaires

  1. socket send et recv
    Par sebatlante dans le forum Réseau
    Réponses: 24
    Dernier message: 29/08/2007, 01h34
  2. [C]Proxy send sur un socket fermé par un RST
    Par pier* dans le forum Développement
    Réponses: 1
    Dernier message: 14/08/2006, 21h27
  3. [Socket] Send/Recv type double sur architectures différentes
    Par nicolas.pied dans le forum Réseau
    Réponses: 4
    Dernier message: 31/03/2006, 20h33
  4. Question sur les fonctions "send()" et "recv(
    Par damien99 dans le forum MFC
    Réponses: 6
    Dernier message: 10/02/2006, 20h47

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo