Diferenças
Aqui você vê as diferenças entre duas revisões dessa página.
Ambos lados da revisão anterior Revisão anterior Próxima revisão | Revisão anterior | ||
pua:exemplo_de_rpc [2008/08/14 00:41] – maziero | pua:exemplo_de_rpc [2020/08/18 22:51] (atual) – edição externa 127.0.0.1 | ||
---|---|---|---|
Linha 1: | Linha 1: | ||
+ | ====== Exemplo de uso de RPC ====== | ||
+ | |||
+ | |||
+ | Em RPC, o único vínculo explícito entre o servidor e seus clientes é a especificação da interface do serviço oferecido. | ||
+ | |||
+ | <code c addsub.x> | ||
+ | /* addsub.x : definição da interface */ | ||
+ | |||
+ | #define PROGRAM_NUMBER 12345678 | ||
+ | #define VERSION_NUMBER 1 | ||
+ | |||
+ | /* tipo de dado que será passado aos procedimentos remotos */ | ||
+ | |||
+ | struct operands | ||
+ | { | ||
+ | int x; | ||
+ | int y; | ||
+ | }; | ||
+ | |||
+ | /* Definição da interface que será oferecida aos clientes */ | ||
+ | |||
+ | program ADDSUB_PROG | ||
+ | { | ||
+ | | ||
+ | { | ||
+ | int ADD (operands) = 1; | ||
+ | int SUB (operands) = 2; | ||
+ | } | ||
+ | = VERSION_NUMBER; | ||
+ | } | ||
+ | = PROGRAM_NUMBER; | ||
+ | </ | ||
+ | |||
+ | Essa definição de interface deve ser compilada pelo utilitário '' | ||
+ | |||
+ | < | ||
+ | espec: | ||
+ | espec: | ||
+ | total 28 | ||
+ | -rw-r--r-- | ||
+ | -rw-r--r-- | ||
+ | -rw-r--r-- | ||
+ | -rw-r--r-- | ||
+ | -rw-r--r-- | ||
+ | </ | ||
+ | |||
+ | A seguir devem ser escritos o cliente e o servidor que irão se comunicar usando essa especificação. Como o servidor é passivo e só aguarda, processa e responde pedidos, seu código é bastante simples: | ||
+ | |||
+ | <code c server.c> | ||
+ | /* Arquivo server.c: um servidor RPC simples */ | ||
+ | #include < | ||
+ | #include " | ||
+ | |||
+ | /* implementação da função add */ | ||
+ | int * add_1_svc (operands *argp, struct svc_req *rqstp) | ||
+ | { | ||
+ | | ||
+ | |||
+ | | ||
+ | | ||
+ | | ||
+ | } | ||
+ | |||
+ | /* implementação da função sub */ | ||
+ | int * sub_1_svc (operands *argp, struct svc_req *rqstp) | ||
+ | { | ||
+ | | ||
+ | |||
+ | | ||
+ | | ||
+ | | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | O código do cliente é um pouco mais complexo, pois ele precisa obter uma referência do servidor antes de submeter seus pedidos: | ||
+ | |||
+ | <code c client.c> | ||
+ | /* Arquivo client.c: um cliente RPC simples */ | ||
+ | |||
+ | #include < | ||
+ | #include " | ||
+ | |||
+ | /* função que chama a RPC add_1 */ | ||
+ | int add (CLIENT *clnt, int x, int y) | ||
+ | { | ||
+ | | ||
+ | int *result; | ||
+ | |||
+ | /* junta os parâmetros em um struct */ | ||
+ | ops.x = x; | ||
+ | ops.y = y; | ||
+ | |||
+ | /* chama a função remota */ | ||
+ | | ||
+ | if (result == NULL) | ||
+ | { | ||
+ | | ||
+ | exit (1); | ||
+ | } | ||
+ | |||
+ | | ||
+ | } | ||
+ | |||
+ | /* função que chama a RPC sub_1 */ | ||
+ | int sub (CLIENT *clnt, int x, int y) | ||
+ | { | ||
+ | | ||
+ | int *result; | ||
+ | |||
+ | /* junta os parâmetros em um struct */ | ||
+ | ops.x = x; | ||
+ | ops.y = y; | ||
+ | |||
+ | /* chama a função remota */ | ||
+ | | ||
+ | if (result == NULL) | ||
+ | { | ||
+ | printf (" | ||
+ | exit (1); | ||
+ | } | ||
+ | | ||
+ | } | ||
+ | |||
+ | int main( int argc, char *argv[]) | ||
+ | { | ||
+ | | ||
+ | int x,y; | ||
+ | |||
+ | /* verifica se o cliente foi chamado corretamente */ | ||
+ | if (argc!=4) | ||
+ | { | ||
+ | fprintf (stderr," | ||
+ | exit (1); | ||
+ | } | ||
+ | |||
+ | /* cria uma struct CLIENT que referencia uma interface RPC */ | ||
+ | clnt = clnt_create (argv[1], ADDSUB_PROG, | ||
+ | |||
+ | /* verifica se a referência foi criada */ | ||
+ | if (clnt == (CLIENT *) NULL) | ||
+ | { | ||
+ | clnt_pcreateerror (argv[1]); | ||
+ | exit(1); | ||
+ | } | ||
+ | |||
+ | /* obtém os dois inteiros que serão passados via RPC */ | ||
+ | x = atoi (argv[2]); | ||
+ | y = atoi (argv[3]); | ||
+ | |||
+ | /* executa os procedimentos remotos */ | ||
+ | | ||
+ | | ||
+ | |||
+ | | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | Em seguida, cliente e servidor podem ser compilados separadamente, | ||
+ | |||
+ | < | ||
+ | $ cc server.c addsub_svc.c | ||
+ | $ cc client.c addsub_clnt.c addsub_xdr.c -o client -lnsl | ||
+ | $ ll | ||
+ | total 60 | ||
+ | -rw-r--r-- | ||
+ | -rw-r--r-- | ||
+ | -rw-r--r-- | ||
+ | -rw-r--r-- | ||
+ | -rw-r--r-- | ||
+ | -rwxr-xr-x | ||
+ | -rw-r--r-- | ||
+ | -rwxr-xr-x | ||
+ | -rw-r--r-- | ||
+ | </ | ||
+ | |||
+ | O servidor (arquivo '' | ||