|
RPC是glibc提供的函数参数/返回值封装服务, 并将封装结果通过网络传到服务器.
RPC服务端首先要启动portmapper服务.
测试一个简单的RPC传输示例, 先定义一个模板文件test.x
- program TESTPROG{
- version VERSION{
- int int_echo(int)=1;
- int get_str_len(string)=2;
- int add ( int, int ) = 3;
- }=1;
- }=30000;
复制代码
内含3个函数, 注意其中一个有2个参数.
然后可以用rpcgen生成一个Makefile:
这会生成Makefile, 客户端和服务端的程序, 和函数示例.
我们手工修改一下Makefile
- # This is a template Makefile generated by rpcgen
- # Parameters
- CLIENT = test_client
- SERVER = test_server
- SOURCES_CLNT.c =
- SOURCES_CLNT.h =
- SOURCES_SVC.c =
- SOURCES_SVC.h =
- SOURCES.x = test.x
- TARGETS_SVC.c = test_svc.c test_server.c test_xdr.c
- TARGETS_CLNT.c = test_clnt.c test_client.c test_xdr.c
- TARGETS = test.h test_xdr.c test_clnt.c test_svc.c
- OBJECTS_CLNT = $(SOURCES_CLNT.c:%.c=%.o) $(TARGETS_CLNT.c:%.c=%.o)
- OBJECTS_SVC = $(SOURCES_SVC.c:%.c=%.o) $(TARGETS_SVC.c:%.c=%.o)
- # Compiler flags
- CFLAGS += -g -pipe
- LDLIBS += -lnsl
- RPCGENFLAGS = -N
- # Targets
- all : $(CLIENT) $(SERVER)
- $(TARGETS) : $(SOURCES.x)
- rpcgen $(RPCGENFLAGS) $(SOURCES.x)
- $(OBJECTS_CLNT) : $(SOURCES_CLNT.c) $(SOURCES_CLNT.h) $(TARGETS_CLNT.c)
- $(OBJECTS_SVC) : $(SOURCES_SVC.c) $(SOURCES_SVC.h) $(TARGETS_SVC.c)
- $(CLIENT) : $(OBJECTS_CLNT)
- $(LINK.c) -o $(CLIENT) $(OBJECTS_CLNT) $(LDLIBS)
- $(SERVER) : $(OBJECTS_SVC)
- $(LINK.c) -o $(SERVER) $(OBJECTS_SVC) $(LDLIBS)
- clean:
- $(RM) core $(TARGETS) $(OBJECTS_CLNT) $(OBJECTS_SVC) $(CLIENT) $(SERVER)
复制代码
修改test_server.c服务端的处理函数, 提供3种服务:
- /*
- * This is sample code generated by rpcgen.
- * These are only templates and you can use them
- * as a guideline for developing your own functions.
- */
- #include "test.h"
- int *
- int_echo_1_svc(int arg1, struct svc_req *rqstp)
- {
- static int result;
- //echo.
- result=arg1;
- printf("[RPC1] source=%d, echo=%d\n", arg1, result);
- return &result;
- }
- int *
- get_str_len_1_svc(char *arg1, struct svc_req *rqstp)
- {
- static int result;
- //get strlen.
- result=strlen(arg1);
- printf("[PRC2] str=%s, len=%d\n", arg1, result);
- return &result;
- }
- int *
- add_1_svc(int arg1, int arg2, struct svc_req *rqstp)
- {
- static int result;
- result=arg1+arg2;
- printf("[RPC3] %d+%d=%d\n", arg1, arg2, result);
- return &result;
- }
复制代码
客户端test_client.c, 调用这三种服务:
- /*
- * This is sample code generated by rpcgen.
- * These are only templates and you can use them
- * as a guideline for developing your own functions.
- */
- #include "test.h"
- void
- testprog_1(char *host)
- {
- CLIENT *clnt;
- int *result_1;
- int int_echo_1_arg1=55;
- int *result_2;
- char *get_str_len_1_arg1="Hello, world";
- int *result_3;
- int add_1_arg1=10;
- int add_1_arg2=20;
- clnt = clnt_create (host, TESTPROG, VERSION, "udp");
- if (clnt == NULL) {
- clnt_pcreateerror (host);
- exit (1);
- }
- result_1 = int_echo_1(int_echo_1_arg1, clnt);
- if (result_1 == (int *) NULL) {
- clnt_perror (clnt, "call failed");
- }
- else
- printf("[PRC1] echo %d, source %d\n", *result_1,
- int_echo_1_arg1);
- result_2 = get_str_len_1(get_str_len_1_arg1, clnt);
- if (result_2 == (int *) NULL) {
- clnt_perror (clnt, "call failed");
- }
- else
- printf("[RPC2] return %d, should %d\n", *result_2,
- strlen(get_str_len_1_arg1));
- result_3 = add_1(add_1_arg1, add_1_arg2, clnt);
- if (result_3 == (int *) NULL) {
- clnt_perror (clnt, "call failed");
- }
- else
- printf("[PRC3] %d+%d=%d\n", add_1_arg1, add_1_arg2,
- *result_3);
- clnt_destroy (clnt);
- }
复制代码
OK, 可以调用make了.
生成可执行程序test_server和test_client.
我们启动./test_server, 用rpcinfo看看:
$rpcinfo -p 127.0.0.1
program vers proto port
100000 2 tcp 111 portmapper
30000 1 udp 36307
30000 1 tcp 34883
Bingo! 启动成功.
再开个终端, 尝试一下调用.
./test_client 127.0.0.1
[PRC1] echo 55, source 55
[RPC2] return 12, should 12
[PRC3] 10+20=30
正是我们期望的.
------------------------------------------
原创作品, 张力辉 <swordhui@263.net>
------------------------------------------ |
|