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 :

RPC - XDR : Transfert de liste chainée


Sujet :

Réseau C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Inscrit en
    Janvier 2008
    Messages
    52
    Détails du profil
    Informations forums :
    Inscription : Janvier 2008
    Messages : 52
    Par défaut RPC - XDR : Transfert de liste chainée
    Bonjour,

    - problème : mon code compile, tourne, mais n'affiche pas le résultat escompté

    - code :

    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
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    index.h
    #include <rpc/types.h>
    
    #define RPCSUCCESS 0
    #define PROC_REC 10
    #define PROC_AJ 11
    #define PROC_AF 12
    #define PROC_LIST 13
    #define PROC_KILL 14
    #define NB_PROG 20000000 
    #define NB_VERS 1
    
    struct ligne {
    	char *nom;
    	int tel;
    };
    
    struct Noeud {
    	char *nom;
    	int tel;
    	struct Noeud * ptr;
    };
    
    typedef struct ligne ligne;
    typedef struct Noeud Noeud;
    
    extern void * affiche_1();
    extern ligne * recherche_1();
    extern int * ajout_1();
    extern bool_t xdr_ligne();
    extern bool_t xdr_noeud();
    extern Noeud * lister();
    extern void affiche_elt();
    extern void * stop_1();
    
    
    
    index.c
    #include <stdio.h>
    #include "index.h"
    
    menu(){
      printf ( "\n       Menu:\n");
      printf ( "1) Rechercher un nom\n");
      printf ( "2) Ajouter un nom\n");
      printf ( "3) Faire afficher au srv\n");
      printf ( "4) lister les noms\n");
      printf ( "8) Quiter\n\n");
      printf ( "Faites votre choix + Enter: ");
    }
    
    main (int argc, char ** argv) {
      char *chaine = (char *)malloc(256), telephone[256];
      ligne *resultat, nouvelle;
      Noeud * noeud;
     
      menu();
      while ( gets(chaine) ) {
        switch ( chaine[0] ) {
     
       [...]
    
        case '4': /* Liste de noms... */
          printf ( "Liste de(s) nom(s)...\n");
    	affiche_elt( lister() );
          printf ("\n");
          break;
        case '8': /* quitter le client */
          exit(0);
          break;
        default: 
          printf ("Option non (encore) implémenté...");
        }
        menu();
      }
    }
    
    
    
    index_clnt.c
    #include <stdio.h>
    #include <rpc/types.h>
    #include <rpc/xdr.h>
    #include <rpc/clnt.h>
    #include <string.h>
    #include "index.h"
    
    int d;
    char nom_machine[] = "localhost";
    char liste[256];
    struct ligne ligne_retour;
    struct Noeud noeud_retour;
    
       [...]
    
    Noeud * lister(){
    	int rep;
    	if ( ( rep = callrpc(nom_machine,NB_PROG,NB_VERS,PROC_LIST,xdr_void,NULL,xdr_noeud,&noeud_retour) ) != 0) {
    		clnt_perrno(rep);
    		puts("\n");
    	}
    }
    
    void affiche_elt(Noeud * N) {
    	if ( N != NULL ) {
    		printf("%s %d\n",N->nom,N->tel);
    		affiche_elt( N->ptr );
    	}	
    }
    
    
    
    index_svc.c
    #include <stdio.h>
    #include <rpc/types.h>
    #include <rpc/xdr.h>
    #include <rpc/clnt.h>
    #include "index.h"
    
    
    main(){
    
       [...]
    
    	if ( registerrpc(NB_PROG, NB_VERS, PROC_LIST, lister, xdr_void, xdr_noeud) != RPCSUCCESS ) {
    		perror("Echec Recherche");
    		exit(2);
    	}
    
    	svc_run();
    }
    
    
    
    index_local.c
    #include <stdio.h>
    #include <errno.h>
    #include <stdlib.h>
    #include <string.h>
    #include "index.h"
    
    #define NOM_FICHIER "index.data"
    
    
    /* Recherche de la ligne contenant le nom correspondant... */
    
    static ligne entree;
    static ligne * l = NULL;
    static char buf[256];
    Noeud * ajout;
    
       [...]
    
    Noeud * lister() {
      FILE *f;
      int t;
      Noeud * tete = NULL;
    
      if ((f = fopen (NOM_FICHIER, "r")) == NULL) perror ("svc: fopen ");
      else {
        if ( fscanf(f,"%s%d", buf, &t ) > 0 ) {
           ajout = malloc( sizeof(struct Noeud) );
           tete = ajout;
           ajout->nom = strdup( buf );
           ajout->tel = t;
           while ( fscanf(f,"%s%d", buf, &t ) != EOF ) {
             ajout->ptr = malloc( sizeof(struct Noeud) );
             ajout = ajout->ptr;
             ajout->nom = strdup( buf );
             ajout->tel = t;
           }
        }
        ajout->ptr = NULL;
        fclose ( f );
      }
      /* DEBUG */ printf("\nListe de(s) nom(s) :\n"); affiche_elt(tete);
      return tete;
    }
    
    void affiche_elt(Noeud * N) {
    	if ( N != NULL ) {
    		printf("%s %d\n",N->nom,N->tel);
    		affiche_elt( N->ptr );
    	}	
    }
    
    
    
    index_xdr.c
    #include <stdio.h>
    #include <rpc/types.h>
    #include <rpc/xdr.h>
    #include <rpc/rpc.h>
    #include "index.h"
    
       [...]
    
    bool_t xdr_noeud(XDR * flot,struct Noeud * n) {
    	return xdr_wrapstring(flot, &n->nom) &&
    		 xdr_int(flot, &n->tel) &&
    			xdr_pointer(flot,(char **)&n->ptr,sizeof(struct Noeud),xdr_noeud);
    }
    J'ai eu beau chercher, je ne vois pas... mon filtre xdr_noeud est a priori bon, non?
    Pourtant, j'obtiens ce résultat...

    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
    Client :
    [Iloyo@localhost XDR-RPC]$ ./index
    
           Menu:
    1) Rechercher un nom
    2) Ajouter un nom
    3) Faire afficher au srv
    4) lister les noms
    8) Quiter
    
    Faites votre choix + Enter: 4
    Liste de(s) nom(s)...
    
    
           Menu:
    1) Rechercher un nom
    2) Ajouter un nom
    3) Faire afficher au srv
    4) lister les noms
    8) Quiter
    
    
    Serveur :
    [root@localhost XDR-RPC]# ./index_svc 
    
    Liste de(s) nom(s) :
    toto 5432
    titi 3456789
    tutu 2345678
    Ma liste de noms est donc correctement créée mais n'est pas ou mal retournée a mon client...
    quelqu'un aurait-il une explication? une solution??

    Merci

  2. #2
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 391
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 391
    Par défaut
    Désolé, je n'ai jamais transmis une liste chaînée en RPC.
    Je te conseillerais plutôt de la sérialiser pour le transport... (la transmettre sous forme de tableau, quoi).
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  3. #3
    Membre averti
    Inscrit en
    Janvier 2008
    Messages
    52
    Détails du profil
    Informations forums :
    Inscription : Janvier 2008
    Messages : 52
    Par défaut
    Solution :


    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
    index.h
    
    #include <rpc/types.h>
    
    #define RPCSUCCESS 0
    #define PROC_REC 10
    #define PROC_AJ 11
    #define PROC_AF 12
    #define PROC_LIST 13
    #define PROC_KILL 14
    #define NB_PROG 20000000 
    #define NB_VERS 1
    
    struct ligne { char *nom; int tel; };
    struct Noeud { struct ligne L; struct Noeud * ptr; };
    
    typedef struct ligne ligne;
    typedef struct Noeud Noeud;
    
    extern ligne * recherche_1();
    extern int * ajout_1();
    extern void * affiche_1();
    extern Noeud * lister();
    extern void * stop_1();
    
    extern bool_t xdr_ligne();
    extern bool_t xdr_noeud();
    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
    index.c
    #include <stdio.h>
    #include "index.h"
    
    menu(){
      printf ( "\n       Menu:\n");
      printf ( "1) Rechercher un nom\n");
      printf ( "2) Ajouter un nom\n");
      printf ( "3) Faire afficher au srv\n");
      printf ( "4) lister les noms\n");
      printf ( "5) Terminer le serveur\n");
      printf ( "6) Recherche avec callback\n");
      printf ( "7) Connecter a un autre srv \n");
      printf ( "8) Quiter\n\n");
      printf ( "Faites votre choix + Enter: ");
    }
    
    main (int argc, char ** argv) {
      char * chaine = (char *)malloc(256), telephone[256];
      ligne * resultat;
      ligne nouvelle;
      Noeud * N, * noeud;
    
     
      menu();
      while ( gets(chaine) ) {
        switch ( chaine[0] ) {
        case '1': /* recherche une entree dans l'index */
          printf ( "Recherche nom : "); gets(chaine);
          resultat = recherche_1( &chaine );
          printf ( "\n\tNom : %s\t tel : %d\n\n", resultat -> nom, resultat -> tel );
          free(resultat);
          break;
        case '2': /* ajoute une entree  */
          printf ( "Ajout Nom : "); gets(chaine); nouvelle.nom = chaine;
          printf ("Tel : "); scanf ("%d", &nouvelle.tel ); getchar();
          printf ("Ajout: %d \n", *(ajout_1( &nouvelle )) );
          break;
        case '3': /* affiche... */
          printf ( "Afficher : "); gets(chaine);
          printf ("%s affiche sur le serveur distant\n", chaine); affiche_1(&chaine);
          break;
        case '4': /* Liste de noms... */
          noeud = lister();
          if ( noeud != NULL ) {
    	N = noeud;
    	printf ( "\nListe de(s) nom(s)...\n");
    	while( N != NULL ) { printf("%s %d\n",N->L.nom,N->L.tel); N = N->ptr; }
          } else perror("Erreur de listage\n");
          free(noeud);
          break;
        case '5': /* Terminer Serveur... */
          printf ( "Mot de passe : "); gets(chaine); stop_1(&chaine);
          break;
        case '8': /* quitter le client */
          exit(0);
          break;
        default: 
          printf ("Option non (encore) implemente...");
        }
        menu();
      }
    }
    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
    index_clnt.c
    #include <stdio.h>
    #include <rpc/types.h>
    #include <rpc/xdr.h>
    #include <rpc/clnt.h>
    #include <string.h>
    #include "index.h"
    
    char nom_machine[] = "localhost";
    
    ligne * recherche_1(char ** nom){
    	ligne * ligne_retour = malloc( sizeof(ligne) );
    	clnt_perrno( callrpc(nom_machine,NB_PROG,NB_VERS,PROC_REC,xdr_wrapstring,nom,xdr_ligne,ligne_retour) );
    	return ligne_retour;
    }
    
    int * ajout_1(ligne * a_ajouter) {
    	int d;
    	clnt_perrno( callrpc(nom_machine,NB_PROG,NB_VERS,PROC_AJ,xdr_ligne,a_ajouter,xdr_int,&d) );
    	return &d;
    }
    
    void * affiche_1(char ** s){ clnt_perrno( callrpc(nom_machine,NB_PROG,NB_VERS,PROC_AF,xdr_wrapstring,s,xdr_void,NULL) ); }
    
    Noeud * lister(){
    	Noeud * noeud_retour = malloc( sizeof(Noeud) );
    	clnt_perrno( callrpc(nom_machine,NB_PROG,NB_VERS,PROC_LIST,xdr_void,NULL,xdr_noeud,noeud_retour) );
    	return noeud_retour;
    }
    
    void * stop_1(char ** mot_de_passe){
    	clnt_perrno( callrpc(nom_machine,NB_PROG,NB_VERS,PROC_KILL,xdr_wrapstring,mot_de_passe,xdr_void,NULL) );
    }
    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
    index_svc.c
    #include <stdio.h>
    #include <rpc/types.h>
    #include <rpc/xdr.h>
    #include <rpc/clnt.h>
    #include "index.h"
    
    main(){
    	if ( registerrpc(NB_PROG, NB_VERS, PROC_REC, recherche_1, xdr_wrapstring, xdr_ligne) != RPCSUCCESS ) {
    		perror("Echec Recherche");
    		exit(2);
    	}
    
    	if ( registerrpc(NB_PROG, NB_VERS, PROC_AJ, ajout_1, xdr_ligne, xdr_int) != RPCSUCCESS ) {
    		perror("Echec Ajout");
    		exit(2);
    	}
    
    	if ( registerrpc(NB_PROG, NB_VERS, PROC_AF, affiche_1, xdr_wrapstring, xdr_void) != RPCSUCCESS ) {
    		perror("Echec Recherche");
    		exit(2);
    	}
    
    	if ( registerrpc(NB_PROG, NB_VERS, PROC_LIST, lister, xdr_void, xdr_noeud) != RPCSUCCESS ) {
    		perror("Echec Recherche");
    		exit(2);
    	}
    
    	if ( registerrpc(NB_PROG, NB_VERS, PROC_KILL, stop_1, xdr_wrapstring, xdr_void) != RPCSUCCESS ) {
    		perror("Echec Stop");
    		exit(2);
    	}
    
    	svc_run();
    }
    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
    index_local.c
    /* 
    
       Gestion d'un index telephonique 
       (pour etre server RPC avec rpcgen)
    
       fichier donnee: lignes ascii de la forme "nom telephone(entier)" 
    
    */
    
    #include <stdio.h>
    #include <errno.h>
    #include <stdlib.h>
    #include <string.h>
    #include "index.h"
    
    #define NOM_FICHIER "index.data"
    
    
    /* Recherche de la ligne contenant le nom correspondant... */
    
    static ligne entree;
    static ligne * l = NULL;
    static char buf[256];
    Noeud * ajout;
    
    ligne * recherche_1 ( char ** nom ) {
      FILE *f;
      int t;
    
      entree.nom = (char *)buf; entree.tel = 0;
      if ((f = fopen (NOM_FICHIER, "r")) == NULL) {perror ("svc: fopen ");}
      else {
        while ( fscanf(f,"%s%d", buf, &t ) != EOF ) {
          if ( !strcmp( *nom, buf) ) {
    	entree.tel = t;
    	fclose ( f );
    	return ( &entree );
          }
        }
        fclose ( f );
      } /* entry not found: return empty string */
      entree.nom[0] = '\0';
      return ( &entree );
    }
    
    /* Ajout d'une ligne si pas deja presente... */
    
    static int status_ajout;
    
    int * ajout_1 ( ligne * a_ajouter ) {
      FILE *f;
      ligne *test;
    
      status_ajout = 0;
      test = recherche_1 ( &(a_ajouter->nom) );
      if ( ! (test->tel) ) {
        f = fopen ( NOM_FICHIER, "a" );
        fprintf (f, "%s %d\n", a_ajouter->nom, a_ajouter->tel);
        fclose(f);
        status_ajout = 1;
      }
      return ( &status_ajout );
    }
    
    /* Affiche une chaine de caractere... */
    
    void * affiche_1 ( char ** s ) {
      printf ( "%s\n", *s ); fflush (stdout);
      return ((void *)1);
    }
    
    /* Liste chainée */
    Noeud * lister() {
      FILE *f;
      int t;
      int nb_num = 0;
      Noeud * head = NULL;
    
      if ((f = fopen (NOM_FICHIER, "r")) == NULL) perror ("svc: fopen ");
      else {
        if ( fscanf(f,"%s%d", buf, &t ) > 0 ) {
           ajout = malloc( sizeof(Noeud) );
           head = ajout;
           ajout->L.nom = strdup( buf );
           ajout->L.tel = t;
           nb_num++;
           while ( fscanf(f,"%s%d", buf, &t ) != EOF ) {
             ajout->ptr = malloc( sizeof(Noeud) );
             ajout = ajout->ptr;
             ajout->L.nom = strdup( buf );
             ajout->L.tel = t;
             nb_num++;
           } // while()
           ajout->ptr = NULL;
           fclose ( f );
        } // if()
      } // else{}
      if ( nb_num == 0 ) {
    	head = malloc( sizeof(Noeud) );
    	head->L.nom = strdup("Aucun numero dans l annuaire");
    	head->L.tel = NULL;
    	head->ptr = NULL;
      }
      /* DEBUG */  Noeud * N = head; printf("\nListe de(s) nom(s) :\n"); while( N != NULL ) { printf("%s %d\n",N->L.nom,N->L.tel); N = N->ptr; }
      return head;
    }
    
    /* Terminer le Serveur */
    void * stop_1(char ** mot_de_passe) {
    	char pwd[] = "password";
    	if ( strcmp( *mot_de_passe , pwd ) == 0 ) {
    		printf("Arret Serveur\n\n"); fflush(stdout);
    		exit(0);
    	}
    }
    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
    index_xdr.c
    #include <stdio.h>
    #include <rpc/types.h>
    #include <rpc/xdr.h>
    #include <rpc/rpc.h>
    #include "index.h"
    
    bool_t xdr_ligne(XDR * flot,ligne * ptr) {
           return xdr_wrapstring(flot, &ptr->nom) && xdr_int(flot, &ptr->tel);
    }
    
    bool_t xdr_noeud(XDR * flot,Noeud * n) {
    	return xdr_ligne(flot, &n->L) && xdr_pointer(flot,(void **)&n->ptr,sizeof(Noeud),xdr_noeud);
    }

    Voila... comme quoi, avec persévérance... on y arrive toujours !!

    Bon ok, tout mon programme n'est pas fini, mais l'essentiel pour la compréhension est là !!

    Bon courage pour ceux que cela intéresse !!

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

Discussions similaires

  1. Réponses: 12
    Dernier message: 08/02/2005, 23h42
  2. Bibliothèque de listes chainées
    Par gege2061 dans le forum C
    Réponses: 29
    Dernier message: 17/12/2004, 20h15
  3. copie de liste chainée
    Par tomsoyer dans le forum C++
    Réponses: 15
    Dernier message: 31/08/2004, 18h20
  4. Trie liste chaine
    Par Congru dans le forum C
    Réponses: 2
    Dernier message: 30/03/2004, 19h05
  5. tri de liste chainée
    Par RezzA dans le forum C
    Réponses: 7
    Dernier message: 26/01/2003, 20h25

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