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即可
功能是计算字符串长度。