美文网首页我爱编程
rpcgen的简单讲解及例子程序

rpcgen的简单讲解及例子程序

作者: hades2013 | 来源:发表于2018-05-28 11:02 被阅读0次

    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程序

    相关文章

      网友评论

        本文标题:rpcgen的简单讲解及例子程序

        本文链接:https://www.haomeiwen.com/subject/fxvwjftx.html