rpcgen的簡單講解及例子程序

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>.

複製代碼

部分選項的解釋:ubuntu

  • -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.cbash

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.ctcp

修改rpcgen生成的源碼文件

修改rpc_client.c :ide

/*
 * 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, 在命令行運行ui

$ ./test_server &
複製代碼

而後運行this

$ ./math_client 127.0.0.1
複製代碼

按照提示輸入內容,測試rpc程序

相關文章
相關標籤/搜索