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 :

structure client : probleme accès champs / sendto/ recvfrom


Sujet :

Réseau C

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Mars 2010
    Messages
    115
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2010
    Messages : 115
    Points : 62
    Points
    62
    Par défaut structure client : probleme accès champs / sendto/ recvfrom
    bonjour, j'essaye de faire un client udp ipv4, en définissant une structure pour un client, cependant, lorsque j'essaye d'accéder à un champ de celle-ci, j'ai des erreur de compilation.
    je ne comprends pas pourquoi, et c'est pourquoi je demande votre aide.

    voici la structure définissant un client:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    typedef struct
    {
        int socket;  // client's socket, default -1
        struct sockaddr_in myaddr;  // client's adress datas
        socklen_t recsize;  // size of adress' structure
        struct sockaddr_in dest; // server's adress datas
    } client_ipv4;
    voici le code dans lequel j'essaye d'utiliser les champs de la structure:
    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
     
    int connect_to_server_ipv4(const char * adr, const char * port,client_ipv4 * tab_client)
    {
      int sock= -1;
     
      memset(&(tab_client.dest), '\0', sizeof(struct sockaddr_in));
     
      // create socket 
      if((sock = socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP)) == -1)
      {
    	perror("socket");
    	exit(EXIT_FAILURE);
      }
     
      // get addr from command line and convert it
      if(inet_pton(AF_INET,adr, &( ( tab_client.dest).sin_addr) )!= 1)
      {
    	perror("inet_pton ipv4");
    	close(sock);
    	exit(EXIT_FAILURE);
      }
     
      /* Connection datas */
      (tab_client.dest).sin_family     = AF_INET;
      (tab_client.dest).sin_port        = htons(atoi(port));
      (tab_client.dest).recsize         = sizeof(struct sockaddr_in);
     
      printf("Connection à %s on port %d established in Ipv4\n",
    			  inet_ntoa((tab_client.dest).sin_addr),
    			  htons((tab_client.dest).sin_port));
      return -1;
    }
     
    int communicate_with_server (client_ipv4 * tab_client, int sock)
    {
      int sbuf = 0;
      char w_buffer[BUF_SIZE];
      char r_buffer[BUF_SIZE];
     
      memset(w_buffer, '\0', sizeof(char) * BUF_SIZE);
      memset(r_buffer, '\0', sizeof(char) * BUF_SIZE);
     
      fd_set readfd;
      fd_set readfd2;
     
      while (1)
      {
        FD_ZERO(&readfd);
        FD_SET(0, &readfd);
        FD_SET(sock,&readfd);
     
        if( select (sock+1,&readfd, NULL,NULL,NULL) < 0 )
        {
          perror("select");
          return -1;
        }
     
        readfd2 = readfd;
     
        // read inputs from the keyboard
        if( FD_ISSET(0,&readfd) )
        {
              if( read(0,w_buffer,BUF_SIZE) == -1 )
    	  {
    		 perror("read");
    		 return -1;
    	  }
     
    	  if(sendto(sock,w_buffer, 1024, 0,
    		(struct sockaddr *)&(tab_client.dest), 
    				tab_client.recsize) == -1)
    	  {
    		fprintf(stderr,"Fail to send last message\n\r");
    		close(sock);
    		return -1;
    	  }
     
    	  memset(w_buffer,'\0',BUF_SIZE);
        }
     
        readfd = readfd2;
     
        // read inputs from the server socket
        if (FD_ISSET(sock,&readfd))
        {
          if((sbuf = recvfrom(sock, r_buffer, 1024, 0,
    		(struct sockaddr*)&(tab_client.myaddr) , 
    						  &(tab_client.recsize))) == -1)
    	  {
    		perror("recvfrom");
    		close(sock);
    		return -1;
    	  }
    	  if (sbuf == 0)
              {
    		fprintf(stderr,"Server disconnected\n\r");
    		return 1;
              }
              else
              {
    		// display message
    		printf("%s",r_buffer);
    		memset(r_buffer,'\0',BUF_SIZE);
              }
          }
      }
     
      return 1;
    }
    voici les erreurs que le compilateur affiche :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    connect.c: In function ‘connect_to_server_ipv4’:
    connect.c:9: error: request for member ‘dest’ in something not a structure or union
    connect.c:19: error: request for member ‘dest’ in something not a structure or union
    connect.c:27: error: request for member ‘dest’ in something not a structure or union
    connect.c:28: error: request for member ‘dest’ in something not a structure or union
    connect.c:32: error: request for member ‘dest’ in something not a structure or union
    connect.c:33: error: request for member ‘dest’ in something not a structure or union
    connect.c: In function ‘communicate_with_server’:
    connect.c:73: error: request for member ‘dest’ in something not a structure or union
    connect.c:74: error: request for member ‘recsize’ in something not a structure or union
    connect.c:90: error: request for member ‘myaddr’ in something not a structure or union
    connect.c:91: error: request for member ‘recsize’ in something not a structure or union
    make: *** [connect.o] Erreur 1
    Merci de votre compréhension

  2. #2
    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
    tab_client est un pointeur dont il faut écrire (*tab_client).dest ou tab_client->dest par exemple, sachant que la deuxième forme est celle qui est recommandée.

  3. #3
    Membre du Club
    Profil pro
    Inscrit en
    Mars 2010
    Messages
    115
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2010
    Messages : 115
    Points : 62
    Points
    62
    Par défaut
    effectivement en faisant comme tu as dis je n'ait plus d'erreur de compilation, cependant je n'arrive pas à comprendre pourquoi je n'ait pas de problème de compilation quand j'initialise les clients dans une fonction, je n'utilise pas de "->"

    voici la fonction dans laquel je n'utilise pas de "->":
    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
     
    /**
     *@fn int init_client (client * tab_client, int it)
     *@brief Initialize a client's struct ipv4
     *@param tab_client Client array
     *@param it Client's index
     *@return 1 On success which is always the case
     */
    int init_client_ipv4(client_ipv4 * tab_client, int it)
    {
      tab_client[it].socket = -1;
      tab_client[it].recsize = sizeof(struct sockaddr_in);
     
      return 1;
    }

  4. #4
    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 la même raison : tab_client est un pointeur de structure client_ipv4. tab_client[it] désigne donc une structure client_ipv4 et l'expression tab_client[it].socket est valide. Si tu veux utiliser l'opérateur ->, tu peux choisir la forme ( &(tab_client[it]) )->socket ou encore (tab_client + it)->socket. Oui, tab_client + it est strictement équivalent à ( &(tab_client[it]) ). De même, pour ta culture, *(tab_client + it) est strictement équivalent à tab_client[it].

  5. #5
    Membre du Club
    Profil pro
    Inscrit en
    Mars 2010
    Messages
    115
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2010
    Messages : 115
    Points : 62
    Points
    62
    Par défaut
    merci de ton explication, je comprends mieux, cependant je trouve quelques difficulté dans la transmission de données (ici chaines de caractère car c'est un tchat udp), les données ne sont pas transmisses aux autres clients. Je ne sais pas si ma connexion est correctement faite côté client, et si sendto et recvfrom possèdent les bons paramètre de ma structure client_ipv4.

    voici ma structure client_ipv4:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    typedef struct
    {
      int socket;  // client's socket, default -1
      struct sockaddr_in client;  // client's adress datas
      socklen_t recsize;  // size of adress' structure
      struct sockaddr_in server; // server's adress datas
    } client_ipv4;
    voici la connexion et la transmission (ici côté 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
    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
     
    // connect with the specified server
    int connect_to_server_ipv4(const char * adr, const char * port,client_ipv4 * tab_client)
    {
      int sock= -1;
     
      // create socket 
      if( ( sock = socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP) ) == -1)
      {
    	perror("socket");
    	return -1;
      }
     
      // get addr from command line and convert it
      if( inet_pton(AF_INET,adr, &( (tab_client->server).sin_addr) )!= 1 )
      {
    	perror("inet_pton ipv4");
    	close(sock);
    	return -1;
      }
     
      /* Connection datas */ 
      memset( &(tab_client->server ), '\0', sizeof(struct sockaddr_in));
      tab_client->server.sin_family      = AF_INET;
      tab_client->server.sin_port        = htons(atoi(port));
      tab_client->recsize                = sizeof(struct sockaddr_in);
     
      // bind addr structure with socket 
      memset( &(tab_client->client ), '\0', sizeof(struct sockaddr_in));
      tab_client->client.sin_family      = AF_INET;
      tab_client->client.sin_port        = htons(0);
      tab_client->client.sin_addr.s_addr = htonl(INADDR_ANY);
      tab_client->recsize                = sizeof(struct sockaddr_in);
     
      if(bind(sock,(struct sockaddr *)&(tab_client->client), tab_client->recsize ) == -1)
      {
    	perror("Error : Bind socket");
    	close(sock);
    	return -1;
      }
      printf("Connection à %s on port %d established in Ipv4\n",
    			  inet_ntoa((tab_client->server).sin_addr),
    			  htons((tab_client->server).sin_port));
     
      return sock;
    }
    //communicate with the server, send message from keyboard and print received message
    int communicate_with_server_ipv4(client_ipv4 * tab_client, int sock)
    {
     
      int size_s = 0;
      int size_r  = 0;
      char w_buffer[BUF_SIZE];
      char r_buffer[BUF_SIZE];
     
      memset(w_buffer, '\0', sizeof(char) * BUF_SIZE);
      memset(r_buffer, '\0', sizeof(char) * BUF_SIZE);
     
      fd_set readfd;
      fd_set readfd2;
     
      while (1)
      {
        FD_ZERO(&readfd);
        FD_SET(0, &readfd);
        FD_SET(sock,&readfd);
     
        if( select (sock+1,&readfd, NULL,NULL,NULL) < 0 )
        {
          perror("select");
          return -1;
        }
     
        readfd2 = readfd;
     
        // read inputs from the keyboard
        if( FD_ISSET(0,&readfd) )
        {
              if( read(0,w_buffer,BUF_SIZE) == -1 )
    	  {
    		 perror("read");
    		 return -1;
    	  }
     
    	  if((size_s= sendto(sock,w_buffer, BUF_SIZE, 0,
    		(struct sockaddr *)&(tab_client->server),
    						 tab_client->recsize) ) == -1)
    	  {
    		fprintf(stderr,"Error sendto : Fail to send last message\n\r");
    		printf("errno %d\n",errno);
    		close(sock);
    		return -1;
    	  }
    	  memset(w_buffer,'\0',BUF_SIZE);
        }
     
        readfd = readfd2;
     
        // read inputs from the server socket
        if (FD_ISSET(sock,&readfd))
        {
              if((size_r = recvfrom(sock, r_buffer, BUF_SIZE, 0,
    		(struct sockaddr*)&(tab_client->client),
    							&(tab_client->recsize))) == -1)
    	  {
    		perror("Error recvfrom");
    		printf(" recvfrom errno %d\n",errno);
    		close(sock);
    		return -1;
    	  }
    	  if (size_r == 0)
              {
    		fprintf(stderr,"Server disconnected\n\r");
    		return 1;
              }
             else 
             {
    		// display message
    		printf(" r_buffer----> %s",r_buffer);
    		memset(r_buffer,'\0',BUF_SIZE);
             }
         }
      }
     
      return 1;
    }
    Merci de ta compréhension

  6. #6
    Membre du Club
    Profil pro
    Inscrit en
    Mars 2010
    Messages
    115
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2010
    Messages : 115
    Points : 62
    Points
    62
    Par défaut
    bonjour, je voulais savoir, si on pouvais en udp , envoyer et recevoir une structure complète? si oui faudrait-il faire des manipulation spéciale? conversion en chaine de caractère par exemple? comment selon vous, récupérer les différents champs d'une structure envoyer en udp?

    Merci de votre compréhension.

  7. #7
    Membre à l'essai
    Inscrit en
    Octobre 2006
    Messages
    21
    Détails du profil
    Informations forums :
    Inscription : Octobre 2006
    Messages : 21
    Points : 18
    Points
    18
    Par défaut
    le seul, l'unique > ça dépend un peu de la taille de la structure. Le type de données que tu envoies a relativement peu d'importance, l'important, c'est surtout que l'émetteur et le récepteur attendent le même type de données.

    Donc tu peux tout à fait envoyer une structure, en la passant par pointeurs à "recvfrom"/"sendto". Il faut bien veiller à ce que les structures soient les mêmes des deux côtés.

    Ma réponse est valable dans le cadre d'un programme "personnel" et pas distribué, car en réalité, dans ta structure, tu vas avoir des variables de types différents, qui auront une certaine taille. (par exemple, le type "char" pèse 1 octet). Si deux machines avec des types de taille différentes communiquent, les données seront corrompues, car la taille respective de leur structure ne sera pas la même, et certaines données seront "décalées".

  8. #8
    Membre du Club
    Profil pro
    Inscrit en
    Mars 2010
    Messages
    115
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2010
    Messages : 115
    Points : 62
    Points
    62
    Par défaut
    merci de ta réponse,

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

Discussions similaires

  1. acces champs dynamique probleme
    Par coolstuff_ dans le forum Général JavaScript
    Réponses: 1
    Dernier message: 01/05/2006, 17h58
  2. [SQL Server] Petit probleme de champ
    Par Diablo_22 dans le forum Langage SQL
    Réponses: 2
    Dernier message: 21/06/2005, 11h05
  3. Serveur de fichier Samba - problème accès Win XP
    Par rohstev dans le forum Réseau
    Réponses: 2
    Dernier message: 10/06/2005, 08h10
  4. probleme de champs sur crystal report 8.5
    Par abdel6908 dans le forum SAP Crystal Reports
    Réponses: 1
    Dernier message: 10/05/2005, 13h50
  5. [stringtokenizer] probleme avec champs vides
    Par gege2mars dans le forum Langage
    Réponses: 9
    Dernier message: 30/06/2004, 08h25

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