rpcgen 简介
rpcgen可以自动生成RPC服务器程序的大多数代码,它的输入为一个规格说明文件,它的输出为一个C语言的源程序。规格文件(*.x)包含常量、全局数据类型以及远程过程的声明。Rpcgen产生的代码包含了实现客户机和服务器程序所需要的大部分源代码。他包括参数整理、发送RPC报文、参数和结果的外部数据表示以及本地数据表示的转换等。不过在由rpcgen生成的源文件中,没有过程的具体实现,所以程序员必须要手工编辑这些文件,实现这些过程。
自动生成的rpc文件
文件名 | 作用 |
---|---|
Makefile.file | 该文件用于编译所有客户机,服务器代码 |
File_clnt.c | 该文件包含client_stub,程序员一般不用修改 |
File_svc.c | 该文件包含server_stub,程序员一般不用修改 |
File.h | 该文件包含了从说明中产生的所有XDR类型 |
File_xdr.c | 该文件包含了客户机和服务器stub所需的XDR过滤器,程序员一般不用修改 |
File_server.c | 如果生成此文件,则该文件包含远程服务的stub |
File_client.c | 如果生成此文件,则该文件包含了骨架客户机程序。 |
rpcgen的命令行选项
hades@hades:~/c_code$ rpcgen --help
usage: rpcgen infile
rpcgen [-abkCLNTM][-Dname[=value]] [-i size] [-I [-K seconds]] [-Y path] infile
rpcgen [-c | -h | -l | -m | -t | -Sc | -Ss | -Sm] [-o outfile] [infile]
rpcgen [-s nettype]* [-o outfile] [infile]
rpcgen [-n netid]* [-o outfile] [infile]
options:
-a generate all files, including samples
-b backward compatibility mode (generates code for SunOS 4.1)
-c generate XDR routines
-C ANSI C mode
-Dname[=value] define a symbol (same as #define)
-h generate header file
-i size size at which to start generating inline code
-I generate code for inetd support in server (for SunOS 4.1)
-K seconds server exits after K seconds of inactivity
-l generate client side stubs
-L server errors will be printed to syslog
-m generate server side stubs
-M generate MT-safe code
-n netid generate server code that supports named netid
-N supports multiple arguments and call-by-value
-o outfile name of the output file
-s nettype generate server code that supports named nettype
-Sc generate sample client code that uses remote procedures
-Ss generate sample server code that defines remote procedures
-Sm generate makefile template
-t generate RPC dispatch table
-T generate code to support RPC dispatch tables
-Y path directory name to find C preprocessor (cpp)
-5 SysVr4 compatibility mode
--help give this help list
--version print program version
For bug reporting instructions, please see:
<https://bugs.launchpad.net/ubuntu/+source/glibc/+bugs>.
部分选项的解释:
- -a 生成所有源程序,包括客户机和服务器源程序。
- -C 使用ANSI C标准生成编码。
- -c 生成xdr转码C程序。(file_xdr.c)。
- -l 生成客户机stubs。(file_clnt.c)
- -m 生成服务器stubs,但是不生成main函数。(file_svc.c)
- -s rpcgen –C –s tcp file.x,生成服务器stubs,用tcp协议,同时生成了main函数。(file_svc.c)
- -h 生成头文件。
- -Sc 生成骨架客户机程序,(file_client.c),生成后还需要手动添加代码。
- -Ss 生成服务器程序,(file_server.c),生成后还需要手动添加代码。
rpcgen –C file.x
生成file_xdr.c,file.h,Makefile.file,file_svc.c和file_client.c
rpcgen –C –a file.x
比上面多生成了2个文件,file_server.c和file_client.c
rpcgen示例程序
创建规格文件(test.x)
/* filename: test.x */
const ADD = 0;
const SUB = 1;
const MUL = 2;
const DIV = 3;
struct TEST
{
int op; /* 0-ADD, 1-SUB, 2-MUL, 3-DIV */
float arg1;
float arg2;
float result;
};
program TEST_PROG
{
version TEST_VER
{
struct TEST TEST_PROC(struct TEST) = 1;
} = 2;
} = 0x20000001;
用 rpcgen –C –a test.x 生成7个文件
Makefile.test test_client.c test_clnt.c test.h test_server.c test_svc.c test_xdr.c
修改rpcgen生成的源码文件
修改rpc_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
test_prog_2(char *host)
{
CLIENT *clnt;
struct TEST *result_1;
struct TEST test_proc_2_arg;
/* -<<< Add to test*/
char c;
printf("choose the operation:\n\t0---ADD\n\t1---SUB\n\t2---MUL\n\t3---DIV\n");
c = getchar();
switch(c) {
case '0':
test_proc_2_arg.op = ADD;
break;
case '1':
test_proc_2_arg.op = SUB;
break;
case '2':
test_proc_2_arg.op = MUL;
break;
case '3':
test_proc_2_arg.op = DIV;
break;
default:
printf("error:operate/n");
exit(1);
}
printf("input the first number:");
scanf("%f", &test_proc_2_arg.arg1);
printf("input the second number:");
scanf("%f", &test_proc_2_arg.arg2);
/* -<<< Add to test*/
#ifndef DEBUG
clnt = clnt_create (host, TEST_PROG, TEST_VER, "udp");
if (clnt == NULL) {
clnt_pcreateerror (host);
exit (1);
}
#endif /* DEBUG */
result_1 = test_proc_2(&test_proc_2_arg, clnt);
if (result_1 == (struct TEST *) NULL) {
clnt_perror (clnt, "call failed");
}
#ifndef DEBUG
clnt_destroy (clnt);
#endif /* DEBUG */
/* -<<< Add to test*/
printf("The Result is %.3f \n", result_1->result);
/* -<<< Add to test*/
}
int
main (int argc, char *argv[])
{
char *host;
if (argc < 2) {
printf ("usage: %s server_host\n", argv[0]);
exit (1);
}
host = argv[1];
test_prog_2 (host);
exit (0);
}
修改test_server.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"
struct TEST *
test_proc_2_svc(struct TEST *argp, struct svc_req *rqstp)
{
static struct TEST result;
/*
* insert server code here
*/
/* -<<< Add to test*/
switch(argp->op){
case ADD:
result.result = argp->arg1 + argp->arg2;
break;
case SUB:
result.result = argp->arg1 - argp->arg2;
break;
case MUL:
result.result = argp->arg1 * argp->arg2;
break;
case DIV:
result.result = argp->arg1 / argp->arg2;
break;
default:
break;
}
/* -<<< Add to test*/
return &result;
}
添加完成后执行:
make –f makefile.test
编译生成文件: test_client和test_server,
在命令行运行
$ ./test_server &
然后运行
$ ./math_client 127.0.0.1
按照提示输入内容,测试rpc程序
网友评论