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

Développement Discussion :

probleme de reception de message udp apres envoi


Sujet :

Développement

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    119
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2004
    Messages : 119
    Points : 55
    Points
    55
    Par défaut probleme de reception de message udp apres envoi
    Salut, je développe actuellement une application réseau avec les sockets, qui consiste en gros en deux fichiers qui s'échangent des messages en UDP.
    D'un côté, j'ai un serveur qui écoute sur un port, et de l'autre un client qui envoie au serveur ce que l'utilisateur à écrit sur stdin. Le serveur reçoit le message et lui répond.

    Pour faire ça, j'ai fait à peu près 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
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    int nr;
    fd_set readfds, readfds2;
    FD_ZERO(&readfds);
    FD_SET(STDIN, &readfds);	// stdin
    FD_SET(sockfd, &readfds);	// serveur
    maxSock = sockfd + 1;
    while(1)
    {
    	readfds2 = readfds;
    	nr = select(maxSock, &readfds2, NULL, NULL, NULL);
    	if(nr != -1)
    	{
    		if(FD_ISSET(STDIN, &readfds2))
    		{
    			char msgRecherche[TAILLEMSGSTDIN];
    			receptionSTDIN(msgRecherche);
    			sendMessage(msgRecherche);
    		}
    		if(FD_ISSET(sockfd, &readfds2))
    		{
    			char buf[1024];
    			recvfrom(sockfd, buf, sizeof(buf), 0, (struct sockaddr *)&serveur, &tolen);
    			printf("%s\n", buf);
    		}
    	}
    }
    avec les méthodes suivantes :
    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
    void receptionSTDIN(char *msg)
    {
    	ssize_t length = read(STDIN, msg, TAILLEMSGSTDIN-1);
    	// on remplace le '\n' de fin par un \0
    	char *p = strchr (msg, '\n');
    	if (p)	*p = 0;
    }
    void sendMessage(char *msg)
    {
    	if(sendto(sockfd, msg, strlen(msg), 0, (struct sockaddr *)&serveur, tolen) == -1)
    	{
    		perror("erreur a l'appel de la fonction sendto -> ");
    		leave(1);
    	}
    }
    Les variables sockfd, serveur et tolen sont considérées comme globales, et correspondent respectivement au descripteur de socket, à la structure sockaddr_in relative au serveur et à la taille sizeof de cette structure


    Et maintenant mon problème :
    Avec le code fait ainsi, je n'arrive qu'à avoir le scénario suivant : je lance le programme, j'écris sur stdin, j'envoie la chaîne, je vérifie que le serveur envoie bien la réponse, mais le client bloque sur le select à ce moment-là ! C'est donc qu'il ne reçoit rien ?

    Autre point, peut-être lié au premier, si je remplace dans le code ci-dessus les instructions :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    if(nr != -1)
    {
    	if(FD_ISSET(STDIN, &readfds2))
    par :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    if(nr != -1)
    {
    	printf("reception");
    	if(FD_ISSET(STDIN, &readfds2))
    alors, le mot "reception" va s'afficher dès que j'écrirais sur la console, c'est-à-dire dès que des caractères seront disponibles en lecture sur stdin...


    Je suppose que j'ai du louper une étape, ou mal faire quelque chose, car le serveur qui écoute sur une seule socket en UDP (et pas sur stdin) marche très bien...

    Donc si quelqu'un avait une idée, je suis preneur !!


    Merci d'avance !!

  2. #2
    Membre du Club
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    119
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2004
    Messages : 119
    Points : 55
    Points
    55
    Par défaut
    Ça semble pas intéresser grand monde (comme je vous comprend !!) mais vu que j'ai trouvé une solution à mon problème, je la poste pour les générations futures :
    Mon problème était lié à la fonction select() que je ne devais pas utiliser correctement, du coup j'ai trouvé la fonction poll() qui est plus simple à utiliser et avec laquelle je n'ai plus eu de problème !
    Un exemple de poll() ici : http://www.beej.us/guide/bgnet/outpu...t.html#pollman

    Au passage, il parait que cette fonction est plus gourmande que select() en terme de processeur, mais au moins ça marche !

  3. #3
    Membre expérimenté
    Avatar de granquet
    Profil pro
    Étudiant
    Inscrit en
    Octobre 2005
    Messages
    1 201
    Détails du profil
    Informations personnelles :
    Localisation : France, Pyrénées Orientales (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2005
    Messages : 1 201
    Points : 1 421
    Points
    1 421
    Par défaut
    à priori je ne vois pas d'erreur dans ton premier code.
    je me permet tout de même de poster un code fonctionnel avec la fonction select ...
    c'est codé à la vas-vite, il manque pas mal de controle d'erreurs et 2/3 petites choses pour que ce soit un code "pret à etre mis en prod"

    nota: j'utilise les sockets UDP avec connect, cela permet juste de rattacher un socket à un "peer", et permet d'alleger un peu l'écriture des envois//transmissions en utilisant recv//send en lieu et place de recvfrom//sendto
    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
    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
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <unistd.h>
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <sys/select.h>
    #include <netinet/in.h>
     
    #define PORT 50100
    #define AT "127.0.0.1"
     
    void
    main_loop (int sockfd)
    {
      fd_set master, read_fds;
      char buffer[BUFSIZ];
      int n;
     
      FD_ZERO (&master);
      FD_SET (STDIN_FILENO, &master);
      FD_SET (sockfd, &master);
     
      read_fds = master;
      while (select (sockfd + 1, &read_fds, NULL, NULL, NULL) != -1)
        {
          if (FD_ISSET (STDIN_FILENO, &read_fds))
            {
              fgets (buffer, sizeof (buffer), stdin);
              send (sockfd, buffer, strlen (buffer), 0);
            }
          if (FD_ISSET (sockfd, &read_fds))
            {
              n = recv (sockfd, buffer, sizeof (buffer) - 1, 0);
              if (n > 0)
                {
                  buffer[n] = '\0';
                  printf ("recvd >> %s <<\n", buffer);
                }
            }
          read_fds = master;
        }
      perror ("select:");
      exit (EXIT_FAILURE);
    }
     
    int
    main (void)
    {
      int fd;
      struct sockaddr_in serv_addr;
     
      if ((fd = socket (PF_INET, SOCK_DGRAM, 0)) == -1)
        goto err;
     
      memset (&serv_addr, 0, sizeof (serv_addr));
      serv_addr.sin_family = AF_INET;
      inet_ntoa (AT, &serv_addr.sin_addr);
      serv_addr.sin_port = htons (PORT);
     
      if (connect (fd, (struct sockaddr *) &serv_addr, sizeof (serv_addr)) == -1)
        goto err;
     
      main_loop (fd);
     
    err:
      perror ("main:");
     
      return EXIT_FAILURE;
    }

    fonctionnel seulement sur les systémes ou on peux effectuer une selection sur stdin ... windows est donc exclu

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. ShoutBox et curseur automatique après envoie de message
    Par Rian83 dans le forum Débuter avec Java
    Réponses: 1
    Dernier message: 03/05/2009, 18h31
  2. [WD-2000] Word: problème de reception de lien après envoi de mail
    Par lediz dans le forum Word
    Réponses: 5
    Dernier message: 26/04/2009, 00h49
  3. probleme de reception de message
    Par k_boy dans le forum Outlook
    Réponses: 7
    Dernier message: 11/01/2008, 06h41
  4. Réponses: 1
    Dernier message: 26/09/2007, 00h08
  5. envoi / reception de messages
    Par Snowflake dans le forum C
    Réponses: 4
    Dernier message: 05/01/2006, 14h13

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