RPC pour que les valeurs soient modifiées sur place en C

Contexte

J’écris un code client / serveur RPC de base pour une classe et l’une des conditions est que le côté serveur doit modifier les valeurs sur place. L’objective final est de transmettre un vecteur du client au serveur. Mais comme je viens d’apprendre le RPC, j’ai décidé de partir d’exemples simples. Ci-dessous, j’ai un code simple dans lequel je calcule le carré d’un nombre. Pour cet exemple, je voudrais déjà changer le résultat sur place.

problème

Comme vous pouvez le voir dans mon server.c , j’ai essayé de changer la valeur sur place. Mais pour ceux qui connaissent C, vous pouvez déjà voir que je n’ai pas eu de succès. Lors de l’appel de ./client localhost 4, mon résultat était de 4 et, puisque j’imprime la même valeur que j’ai supposément changée, je m’attendais à ce que ce ne soit plus 4. Comment puis-je modifier correctement la valeur en place?

client.c

 #include  #include "square.h" int main(int argc, char **argv) { CLIENT *cl; square_in in; square_out *outp; if (argc != 3) //err_quit("usage: client  "); exit(0); cl = clnt_create(argv[1], SQUARE_PROG, SQUARE_VERS, "tcp"); in.arg1 = atol(argv[2]); if ( (outp = squareproc_1(&in, cl)) == NULL) //err_quit("%s", clnt_sperror(cl, argv[1])); exit(0); printf("result: %ld\n", in.arg1); exit(0); } 

serveur.c

 // SERVER FILE: server.c #include"rpc/rpc.h" #include"square.h" #include"stdio.h" #include"stdlib.h" #include"math.h" square_out *squareproc_1_svc(square_in *inp,struct svc_req *rqstp) { static square_out out; out.res1 = inp->arg1 * inp->arg1; inp->arg1 = out.res1; return(&out); } 

square.x

 struct square_in { long arg1; }; struct square_out { long res1; }; program SQUARE_PROG { version SQUARE_VERS { square_out SQUAREPROC(square_in) = 1; /* procedure number = 1 */ } = 1; /* version number = 1 */ } = 0x31230000; /* program number = 0x31230000 */ 

    Le code du serveur est généralement dans un processus différent, même sur une machine différente, de sorte qu’il n’est pas “au même endroit”, de sorte qu’il pourrait écrire dans la mémoire du client. L’argument reçu par le serveur est en réalité un pointeur sur une copie des données transmises par le client. Le serveur est donc en train de modifier une copie dans l’espace d’adressage du processus serveur, ce qui n’a aucun effet sur les données d’origine dans l’espace d’adressage du processus client.

    Il existe des langages de définition d’interface qui vous permettent d’annoter des parameters en tant que parameters sortants ou en parameters sortants / sortants afin que le générateur génère un code qui s’attend à ce que le serveur puisse écrire dans la mémoire adressée par le paramètre. Il doit donc renvoyer ces données au client et copiez-le dans la mémoire transmise par le client. Cependant, il semble que vous utilisiez ONC RPC ou similaire, et il n’est pas clair que son langage RPC (RPCL) prenne en charge les parameters externes. Voir rpcgen , section 6.7:

     procedure: type-ident procedure-ident "(" type-ident ")" "=" value 

    Notez qu’un IDL et un générateur associé qui prennent en charge les parameters sortants ne permettent pas vraiment au serveur de modifier la mémoire du client “sur place”. Les résultats du serveur doivent toujours être transmis entre les processus, souvent sur le réseau. Celles-ci fournissent uniquement l’illusion de paramétrages externes du sharepoint vue du code client et du code serveur. Votre exigence est donc douteuse, peut-être pas clairement énoncée.

    MODIFIER:

    Si vous avez vraiment besoin du serveur pour modifier la mémoire du client:

    1. Assurez-vous que le serveur et le client fonctionnent sur le même ordinateur.
    2. Utilisez des API de mémoire partagée spécifiques à un système d’exploitation, telles que shm_open () et mmap (), pour mapper le même bloc de mémoire physique dans les espaces adresse du client et du serveur.
    3. Utilisez RPC pour transmettre l’identifiant (nom) de la mémoire partagée (pas les données réelles stockées dans la mémoire) et appeler le traitement du serveur.
    4. Lorsque le client et le serveur ont ouvert et mappé la mémoire, ils ont tous deux un pointeur (probablement avec des valeurs différentes dans les différents espaces adresse) sur la même mémoire physique. Le serveur sera ainsi en mesure de lire ce que le client y écrit (sans copier). ou transmission) et vice versa.