RPC简单使用

RPC远程过程调用示例
本文介绍了一个简单的RPC远程过程调用示例,通过客户端和服务端代码实现字符串长度的计算功能。该示例涉及RPC的基本概念和服务注册、调用流程。

http://www.cnblogs.com/tzhangofseu/archive/2011/11/13/2247318.html

test.x

1 program TESTPROG {
2     version TESTVERS {
3         int Test(string) = 1;
4     } = 1;
5 } = 0x30000000;
test_local.c
 

#include <stdio.h> #include <stdlib.h>

#include "test.h"

#define HOST "localhost"

int test(char *);

CLIENT * handle;

int main(int argc, char **argv) {     handle = clnt_create(argv[1], TESTPROG, TESTVERS, "tcp");     if (handle == NULL) {         printf("connect errror\n");         exit(1);     }     char a[100] = "gaga";     printf("%d\n", test(a));

    return 0; }

test_remote.c

 

#include <rpc/rpc.h> #include <string.h>

#include "test.h"

int test(char * str) {     return strlen(str);    }

 

执行rpggen test.x生成三个文件

test.h

/*  * Please do not edit this file.  * It was generated using rpcgen. */

#ifndef _TEST_H_RPCGEN #define _TEST_H_RPCGEN

#include <rpc/rpc.h>

#ifdef __cplusplus extern "C" { #endif

#define TESTPROG 0x30000000 #define TESTVERS 1

#if defined(__STDC__) || defined(__cplusplus) #define Test 1 extern  int * test_1(char **, CLIENT *); extern  int * test_1_svc(char **, struct svc_req *); extern int testprog_1_freeresult (SVCXPRT *, xdrproc_t, caddr_t);

#else /* K&R C */ #define Test 1 extern  int * test_1(); extern  int * test_1_svc(); extern int testprog_1_freeresult (); #endif /* K&R C */

#ifdef __cplusplus } #endif

#endif /* !_TEST_H_RPCGEN */

 

test_clnt.c

/*  * Please do not edit this file.  * It was generated using rpcgen. */

#include <memory.h> /* for memset */ #include "test.h"

/* Default timeout can be changed using clnt_control() */ static struct timeval TIMEOUT = { 25, 0 };

int * test_1(char **argp, CLIENT *clnt) {     static int clnt_res;

    memset((char *)&clnt_res, 0, sizeof(clnt_res));     if (clnt_call (clnt, Test,         (xdrproc_t) xdr_wrapstring, (caddr_t) argp,         (xdrproc_t) xdr_int, (caddr_t) &clnt_res,         TIMEOUT) != RPC_SUCCESS) {         return (NULL);     }     return (&clnt_res); }

extern CLIENT * handle; static int * ret; int test(char * str) {     char ** arg = &str;     ret = test_1(arg, handle);     return (ret==0)?0:*ret; }

test_svc.c

 

/*  * Please do not edit this file.  * It was generated using rpcgen. */

#include "test.h" #include <stdio.h> #include <stdlib.h> #include <rpc/pmap_clnt.h> #include <string.h> #include <memory.h> #include <sys/socket.h> #include <netinet/in.h>

#ifndef SIG_PF #define SIG_PF void(*)(int) #endif

static void testprog_1(struct svc_req *rqstp, register SVCXPRT *transp) {     union {         char *test_1_arg;     } argument;     char *result;     xdrproc_t _xdr_argument, _xdr_result;     char *(*local)(char *, struct svc_req *);

    switch (rqstp->rq_proc) {     case NULLPROC:         (void) svc_sendreply (transp, (xdrproc_t) xdr_void, (char *)NULL);         return;

    case Test:         _xdr_argument = (xdrproc_t) xdr_wrapstring;         _xdr_result = (xdrproc_t) xdr_int;         local = (char *(*)(char *, struct svc_req *)) test_1_svc;         break;

    default:         svcerr_noproc (transp);         return;     }     memset ((char *)&argument, 0, sizeof (argument));     if (!svc_getargs (transp, (xdrproc_t) _xdr_argument, (caddr_t) &argument)) {         svcerr_decode (transp);         return;     }     result = (*local)((char *)&argument, rqstp);     if (result != NULL && !svc_sendreply(transp, (xdrproc_t) _xdr_result, result)) {         svcerr_systemerr (transp);     }     if (!svc_freeargs (transp, (xdrproc_t) _xdr_argument, (caddr_t) &argument)) {         fprintf (stderr, "%s", "unable to free arguments");         exit (1);     }     return; }

int main (int argc, char **argv) {     register SVCXPRT *transp;

    pmap_unset (TESTPROG, TESTVERS);

    transp = svcudp_create(RPC_ANYSOCK);     if (transp == NULL) {         fprintf (stderr, "%s", "cannot create udp service.");         exit(1);     }     if (!svc_register(transp, TESTPROG, TESTVERS, testprog_1, IPPROTO_UDP)) {         fprintf (stderr, "%s", "unable to register (TESTPROG, TESTVERS, udp).");         exit(1);     }

    transp = svctcp_create(RPC_ANYSOCK, 0, 0);     if (transp == NULL) {         fprintf (stderr, "%s", "cannot create tcp service.");         exit(1);     }     if (!svc_register(transp, TESTPROG, TESTVERS, testprog_1, IPPROTO_TCP)) {         fprintf (stderr, "%s", "unable to register (TESTPROG, TESTVERS, tcp).");         exit(1);     }

    svc_run ();     fprintf (stderr, "%s", "svc_run returned");     exit (1);     /* NOTREACHED */ } int test(char *); static int retcode; int * test_1_svc(char ** arg, struct svc_req * rqstp) {     retcode = test(*arg);     return &retcode; }

生成的两个C文件中有部分是自己添加的。

Makefile

 

all: test_clnt test_svc

USER_MARCOS := DEBUG CFLAGS := -g -static -Wall CC := gcc

SRCCLNT := test_clnt.c test_local.c SRCSVC := test_svc.c test_remote.c

OBJCLNT := $(patsubst %.c,%.o,$(SRCCLNT)) OBJSVC := $(patsubst %.c,%.o,$(SRCSVC))

%.o:%.c     $(CC) $(CFLAGS) $(addprefix -D,$(USER_MARCOS)) -c $< -o $@     test_clnt: ${OBJCLNT}     $(CC) $(CFLAGS) -o test_clnt $(OBJCLNT) test_svc: ${OBJSVC}     $(CC) $(CFLAGS) -o test_svc $(OBJSVC)

clean:     rm -rf test_clnt test_svc $(OBJCLNT) $(OBJSVC)

使用

root下运行

./test_svc

普通用户下运行

./test_clnt localhost即可

功能是计算字符串长度。

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值