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 :

Comment fonctionne recv () ?


Sujet :

Réseau C

  1. #1
    Membre confirmé
    Inscrit en
    Mars 2008
    Messages
    57
    Détails du profil
    Informations forums :
    Inscription : Mars 2008
    Messages : 57
    Par défaut Comment fonctionne recv () ?
    salut,
    j'espère que vous m'aidez a comprendre comment fonctionne recv()
    j'essai de faire ce truc pour une application client/serveur
    le serveur a envoyé 2 messages au client, et le client ne fait recv()
    apres un certain moment (sleep(1)) j'appelle recv()
    alors normalement ces 2 messages sont stockés dans un buffer quelques part
    donc jusque où on peut bufferiser de messages??
    autre chose quand je fais recv(), normalement j'ai eu que le premier messages comment faire pour recuperer le 2ème et plus generalement comment je connais qu'il n'y a plus de messages a recevoir
    merci d'avance

  2. #2
    Membre émérite Avatar de homeostasie
    Homme Profil pro
    Inscrit en
    Mai 2005
    Messages
    939
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France

    Informations forums :
    Inscription : Mai 2005
    Messages : 939
    Par défaut
    Citation Envoyé par mayu5 Voir le message
    salut,
    j'espère que vous m'aidez a comprendre comment fonctionne recv()
    Déjà, as tu jeté un coup d'oeil sur et sur man developpez recv.

    Citation Envoyé par mayu5 Voir le message
    j'essai de faire ce truc pour une application client/serveur
    le serveur a envoyé 2 messages au client, et le client ne fait recv()
    Tu peux toujours montrer un peu ce que tu as fait.

    apres un certain moment (sleep(1)) j'appelle recv()
    Je suis pas certain que tu as une résolution de 1ms...

    alors normalement ces 2 messages sont stockés dans un buffer quelques part
    donc jusque où on peut bufferiser de messages??
    Le buffer, c'est toi qui le déclares donc tu dois bien savoir où les données reçues sont stockées.

    autre chose quand je fais recv(), normalement j'ai eu que le premier messages comment faire pour recuperer le 2ème et plus generalement comment je connais qu'il n'y a plus de messages a recevoir
    merci d'avance
    La fonction recv() est bloquante. Donc tant que ton soft n'est pas bloqué sur cette fonction, c'est que tu reçois des données ou un cas d'erreur.

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

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par mayu5 Voir le message
    j'espère que vous m'aidez a comprendre comment fonctionne recv()
    j'essai de faire ce truc pour une application client/serveur
    le serveur a envoyé 2 messages au client, et le client ne fait recv()
    apres un certain moment (sleep(1)) j'appelle recv()
    alors normalement ces 2 messages sont stockés dans un buffer quelques part
    donc jusque où on peut bufferiser de messages??
    Oui.
    autre chose quand je fais recv(), normalement j'ai eu que le premier messages comment faire pour recuperer le 2ème et plus generalement comment je connais qu'il n'y a plus de messages a recevoir
    Tu boucles sur recv(). C'est comme avec fgets(). Ça devient bloquant quand il n'y a plus rien à lire...

    Nota. En mode connecté (TCP etc.), si recv() retourne 0, c'est que la connexion n'est plus établie. Attention, recv() nest alors plus bloquant et il faut sortir de la boucle.

    Nota : il n'est pas utile d'ajouter des suspensions (ton sleep(1) ne sert à rien)

    Un peu de lecture :

    http://emmanuel-delahaye.developpez.com/reseaux.htm

  4. #4
    Membre confirmé
    Inscrit en
    Mars 2008
    Messages
    57
    Détails du profil
    Informations forums :
    Inscription : Mars 2008
    Messages : 57
    Par défaut
    j'espere que voue seriez plus patient(je suis en grande confusion)
    voici un petit exemple où le serveur envoie plusieurs messages et je veux qu'au moment le client va lire des données normalement tout ces messages sont envoyés
    serveur:

    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
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <unistd.h>
    #define SOCKET_ERROR -1
    #define SERVPORT 23
    #define QUEUE_SIZE 10
    typedef int SOCKET;
    typedef struct sockaddr_in SOCKADDR_IN;
    typedef struct sockaddr SOCKADDR;
    #include<stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <unistd.h>
    #define buffer_size 100
    int main (void){
     
    	SOCKET servsock, clisock;
    	SOCKADDR_IN servaddr, cliaddr;
    	int addrsize = (int) sizeof cliaddr;
        	int sock,sock_err,one;
     
        	servsock = socket (AF_INET, SOCK_STREAM, 0);
    	if(servsock<0)
    	{
    		perror("socket failed()\n");
    		exit(-1);
    	}
            setsockopt(servsock, SOL_SOCKET, SO_REUSEADDR, (char *)&one, sizeof(one)); 
    	memset((char*)&servaddr,0,sizeof(servaddr));
            servaddr.sin_addr.s_addr= htonl (INADDR_ANY);
            servaddr.sin_family= AF_INET;            
            servaddr.sin_port= htons (SERVPORT); 
     
            //error case
        	if((sock_err = bind (servsock, (SOCKADDR *) &servaddr, sizeof servaddr))<0)
    	{
    		perror("bind()failed\n");
    		close(servsock);
    		exit(-1);
    	}	
        	if((sock_err = listen (servsock, QUEUE_SIZE))<0)
    	{
    	perror("listen failed()\n");
    	close(servsock);
    	exit(-1);
    	}
            printf("serveur en attente de connexion...\n");
    	memset((char  *)&cliaddr,0,sizeof(cliaddr)); 
    	cliaddr.sin_addr.s_addr= htonl(SERVPORT);        
            cliaddr.sin_family= AF_INET;            
            cliaddr.sin_port= htons(SERVPORT);     
    	if((clisock=accept(servsock,(SOCKADDR *) &cliaddr, &addrsize))<0)
    	{
    	perror("accept()failed\n");
    	close(servsock);
    	}
     
    	printf("client connecté\n");	
    	char b1[]="bienvenue sur ";
    	sock_err = send(clisock, b1, sizeof(1), 0);
    	if (sock_err != SOCKET_ERROR) printf("Chaine envoy�e : %s\n", b1);
    	char b2[]="le forum ";
    	sock_err = send(clisock, b2, sizeof(b2), 0);
    	if (sock_err != SOCKET_ERROR) printf("Chaine envoy�e : %s\n", b2);
    	char b3[]="de developpez ";
    	sock_err = send(clisock, b3, sizeof(b3), 0);
    	if (sock_err != SOCKET_ERROR) printf("Chaine envoy�e : %s\n", b3);
    	close(servsock);
            return EXIT_SUCCESS;
     
    }
    client:
    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
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
     
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <unistd.h>
    #define SOCKET_ERROR -1
    typedef int SOCKET;
    typedef struct sockaddr_in SOCKADDR_IN;
    typedef struct sockaddr SOCKADDR;
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #define taille 1024
    int main (void)
    {
        int erreur = 0;
        SOCKET sock;
        SOCKADDR_IN sin;
        char buffer[taille];    
       int sock_err,iof;
            // Cr�ation de la socket
            sock = socket(AF_INET, SOCK_STREAM, 0);
            // Configuration de la connexion
            sin.sin_addr.s_addr = inet_addr("127.0.0.1");
            sin.sin_family = AF_INET;
            sin.sin_port = htons(23 );
            // Si l'on a r�ussi � se connecter	
            if(connect(sock, (SOCKADDR *)&sin, sizeof(sin)) != SOCKET_ERROR)
            {
    		sleep(2);
            	printf("Connection � %s sur le port %d\n", inet_ntoa (sin.sin_addr), htons(sin.sin_port));
            	int n;
    		n = recv (sock, buffer, sizeof buffer, 0);
    		if (n > 0)
    			printf("%s\n",buffer);
                    n = recv (sock, buffer, sizeof buffer, 0);
    		if (n > 0)
    			printf("%s\n",buffer);
            }
            else printf("Impossible de se connecter\n");
    	return EXIT_SUCCESS;
    }
    resultat:
    bien le forum

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

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par mayu5 Voir le message
    voici un petit exemple où le serveur envoie plusieurs messages et je veux qu'au moment le client va lire des données normalement tout ces messages sont envoyés
    serveur:
    Euh :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
       char b1[] = "bienvenue sur ";
       sock_err = send (clisock, b1, sizeof (1), 0);
    C'est censé faire quoi ?

    - C'est pas 1 mais probablement b1.
    - C'est pas sizeof, mais strlen() qu'il faut utiliser (on ne transmet pas de zéro avec du texte).

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    Connection ? 127.0.0.1 sur le port 23
    bienvenue sur $
    le forum
    Appuyez sur une touche pour continuer...
    Ca commence à venir. En mettant strlen() partout :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    Connection ? 127.0.0.1 sur le port 23
    bienvenue sur le forum de developpez Æ|♦
    Appuyez sur une touche pour continuer...
    Il va falloir aussi travailler sur la réception...

    Erreur habituelle :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    int n;
    n = recv (sock, buffer, sizeof buffer, 0);
    if (n > 0)
    printf("%s\n",buffer);
    Il faut réserver une place pour le 0 et placer celui-ci à la main :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    {
       <...>
       int n;
       n = recv (sock, buffer, sizeof buffer - 1, 0);
       if (n > 0)
       {
          buffer[n] = 0;
          printf ("%s\n", buffer);
       }
    Et voilà :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    Connection ? 127.0.0.1 sur le port 23
    bienvenue sur le forum de developpez
    Appuyez sur une touche pour continuer...
    Dans le client, il n'y a pas besoin de suspension. Ceci fonctionne :
    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
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
     
    #if defined (WIN32)
    #include <winsock2.h>
    #elif defined (linux)
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    #include <unistd.h>
    #define INVALID_SOCKET -1
    #define SOCKET_ERROR -1
    #define closesocket(s) close (s)
    typedef int SOCKET;
    typedef struct sockaddr_in SOCKADDR_IN;
    typedef struct sockaddr SOCKADDR;
    #endif
     
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
     
    int client (void)
    {
    // Creation de la socket
       SOCKET  sock = socket (AF_INET, SOCK_STREAM, 0);
       SOCKADDR_IN sin = {0};
       char buffer[1024];
    // Configuration de la connexion
       sin.sin_addr.s_addr = inet_addr ("127.0.0.1");
       sin.sin_family = AF_INET;
       sin.sin_port = htons (23);
    // Si l'on a reussi a se connecter
       if (connect (sock, (SOCKADDR *) & sin, sizeof (sin)) != SOCKET_ERROR)
       {
          printf ("Connection a %s sur le port %d\n", inet_ntoa (sin.sin_addr),
                  htons (sin.sin_port));
          {
             int n = recv (sock, buffer, sizeof buffer - 1, 0);
             if (n > 0)
             {
                buffer[n] = 0;
                printf ("%s\n", buffer);
             }
          }
       }
       else
          printf ("Impossible de se connecter\n");
       return EXIT_SUCCESS;
    }
     
    int main (void)
    {
    #if defined (WIN32)
       WSADATA WSAData;
       int erreur = WSAStartup (MAKEWORD (2, 0), &WSAData);
    #else
       int erreur = 0;
    #endif
       client ();
    #if defined (WIN32)
       WSACleanup ();
    #endif
       system ("pause");
     
       return 0;
    }
    Voici le serveur corrigé :
    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
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
     
    #include "psleep/inc/psleep.h"
     
    #if defined (WIN32)
    #include <winsock2.h>
    #elif defined (linux)
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    #include <unistd.h>
    #define INVALID_SOCKET -1
    #define SOCKET_ERROR -1
    #define closesocket(s) close (s)
    typedef int SOCKET;
    typedef struct sockaddr_in SOCKADDR_IN;
    typedef struct sockaddr SOCKADDR;
    #endif
     
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
     
    #define buffer_size 100
    #define SERVPORT 23
    #define QUEUE_SIZE 10
     
    int server (void)
    {
       int ret = EXIT_SUCCESS;
       SOCKET servsock = socket (AF_INET, SOCK_STREAM, 0);
       if (servsock == INVALID_SOCKET)
       {
          perror ("socket failed()\n");
          ret = EXIT_FAILURE;
       }
       else
       {
          int sock_err;
          SOCKADDR_IN servaddr = { 0 };
     
    #if 0
          {
             int one;
             setsockopt (servsock, SOL_SOCKET, SO_REUSEADDR, (char *) &one,
                         sizeof (one));
          }
    #endif
     
          servaddr.sin_addr.s_addr = htonl (INADDR_ANY);
          servaddr.sin_family = AF_INET;
          servaddr.sin_port = htons (SERVPORT);
     
    //error case
          if ((sock_err =
               bind (servsock, (SOCKADDR *) & servaddr, sizeof servaddr)) < 0)
          {
             perror ("bind()failed\n");
             ret = EXIT_FAILURE;
             ret = EXIT_FAILURE;
          }
          else if ((sock_err = listen (servsock, QUEUE_SIZE)) < 0)
          {
             perror ("listen failed()\n");
             ret = EXIT_FAILURE;
             ret = EXIT_FAILURE;
          }
          else
          {
             SOCKET clisock;
             SOCKADDR_IN cliaddr = { 0 };
             int addrsize = (int) sizeof cliaddr;
             cliaddr.sin_addr.s_addr = htonl (SERVPORT);
             cliaddr.sin_family = AF_INET;
             cliaddr.sin_port = htons (SERVPORT);
     
             printf ("serveur en attente de connexion...\n");
     
             if ((clisock =
                  accept (servsock, (SOCKADDR *) & cliaddr,
                          &addrsize)) == INVALID_SOCKET)
             {
                perror ("accept()failed\n");
                ret = EXIT_FAILURE;
             }
             else
             {
                printf ("client connecte\n");
     
                {
                   char b1[] = "bienvenue sur ";
                   sock_err = send (clisock, b1, strlen (b1), 0);
                   if (sock_err != SOCKET_ERROR)
                      printf ("Chaine envoyee : %s\n", b1);
                }
     
                {
                   char b2[] = "le forum ";
                   sock_err = send (clisock, b2, strlen (b2), 0);
                   if (sock_err != SOCKET_ERROR)
                      printf ("Chaine envoyee : %s\n", b2);
                }
     
                {
                   char b3[] = "de developpez.";
                   sock_err = send (clisock, b3, strlen (b3), 0);
                   if (sock_err != SOCKET_ERROR)
                      printf ("Chaine envoyee : %s\n", b3);
                }
             }
          }
          closesocket (servsock);
       }
       return ret;
     
    }
     
    int main (void)
    {
       int ret;
    #if defined (WIN32)
       WSADATA WSAData;
       int erreur = WSAStartup (MAKEWORD (2, 0), &WSAData);
    #else
       int erreur = 0;
    #endif
       ret = server ();
    #if defined (WIN32)
       WSACleanup ();
    #endif
       return ret;
    }
    Pose des questions si tu ne comprends pas. Je conseille néanmoins de lire ceci avant :

    http://emmanuel-delahaye.developpez.com/reseaux.htm

  6. #6
    Membre confirmé
    Inscrit en
    Mars 2008
    Messages
    57
    Détails du profil
    Informations forums :
    Inscription : Mars 2008
    Messages : 57
    Par défaut
    je vous mercie pour votre reponse, ça me permet de fixer des idées correctes
    le probleme etait que j'ai mal compris recv(), en fait dans une connexion tcp on parle pas de messages mais de flux et recv() au moment où elle est appelée elle reçoit tous ce qui est dans le buffer que c'est soit un "message" ou plus.
    alors maitenent je dois voir dans mes données reçus pour pouvoir séparer les différents messages.
    merci encore une fois.

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

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par mayu5 Voir le message
    alors maitenent je dois voir dans mes données reçus pour pouvoir séparer les différents messages.
    Il est d'usage dans un protocole applicatif 'texte', d'utiliser les lignes, c'est à dire de terminer les messages par '\n'.

  8. #8
    Membre confirmé
    Inscrit en
    Mars 2008
    Messages
    57
    Détails du profil
    Informations forums :
    Inscription : Mars 2008
    Messages : 57
    Par défaut
    ben, je vois encore une fois l'utilité des flux xml mais selon mes connaissances il faut parser le flux et construire chaque document a part et ca sera trop bavard ou simplement le traiter comme une chaine de caracteres et chercher le debut et la fin du document

Discussions similaires

  1. [JSF] comment fonctionne <h:message> ?
    Par anitshka dans le forum JSF
    Réponses: 5
    Dernier message: 29/06/2005, 17h36
  2. Comment fonctionne TXmlDocumment ????
    Par almisuifre dans le forum C++Builder
    Réponses: 8
    Dernier message: 18/02/2005, 12h54
  3. comment fonctionne une interface graphique???
    Par elekis dans le forum Langages de programmation
    Réponses: 2
    Dernier message: 27/10/2004, 23h10
  4. Comment fonctionne le ClassExplorer ?
    Par borisd dans le forum C++Builder
    Réponses: 7
    Dernier message: 30/09/2004, 17h44
  5. Comment fonctionne le CVS ?
    Par mathieu dans le forum CVS
    Réponses: 6
    Dernier message: 23/03/2004, 11h26

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