• 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的部分选项

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

    Rpcgen –C –a file.x 比上面多生成了2个文件,file_server.cfile_client.c

     

    Rpcgen示例程序

    规格文件(math.x

    /* filename: math.x */

    const ADD = 0;

    const SUB = 1;

    const MUL = 2;

    const DIV = 3;

    struct MATH

    {

        int op; /* 0-ADD, 1-SUB, 2-MUL, 3-DIV */

        float arg1;

        float arg2;

        float result;

    };

    program MATH_PROG

    {

        version MATH_VER

        {

            struct MATH MATH_PROC(struct MATH) = 1;

        } = 2;

    } = 0x20000001;

     

     rpcgen –C –a math.x 生成7个文件,math.hmath_xdr.cmath_svc.cmath_clnt.cMakefile.mathmath_client.cmath_server.c

    math_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 "math.h"

    void math_prog_2(char *host)

    {

                  CLIENT *clnt;

                  struct MATH  *result_1;

                  struct MATH  math_proc_2_arg;

        /* 2006/07/04 Dongyy Add -> */

        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':

                math_proc_2_arg.op = ADD;

                break;

            case '1':

                math_proc_2_arg.op = SUB;

                break;

            case '2':

                math_proc_2_arg.op = MUL;

                break;

            case '3':

                math_proc_2_arg.op = DIV;

                break;

            default:

                printf("error:operate/n");

                exit(1);

        }

        printf("input the first number:");

        scanf("%f", &math_proc_2_arg.arg1);

        printf("input the second number:");

        scanf("%f", &math_proc_2_arg.arg2);

        /* <- 2006/07/04 Dongyy Add */

     

    #ifndef   DEBUG

                  clnt = clnt_create (host, MATH_PROG, MATH_VER, "udp");

                  if (clnt == NULL) {

                                 clnt_pcreateerror (host);

                                 exit (1);

                  }

    #endif    /* DEBUG */

     

                  result_1 = math_proc_2(&math_proc_2_arg, clnt);

                  if (result_1 == (struct MATH *) NULL) {

                                 clnt_perror (clnt, "call failed");

                  }

    #ifndef   DEBUG

                  clnt_destroy (clnt);

    #endif    /* DEBUG */

        /* 2006/07/04 Dongyy Add -> */

        printf("The Result is %.3f /n", result_1->result);

        /* <- 2006/07/04 Dongyy Add */

    }

    int main (int argc, char *argv[])

    {

                  char *host;

     

                  if (argc < 2) {

                                 printf ("usage: %s server_host/n", argv[0]);

                                 exit (1);

                  }

                  host = argv[1];

                  math_prog_2 (host);

        exit (0);

    }

    math_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 "math.h"

     

    struct MATH *

    math_proc_2_svc(struct MATH *argp, struct svc_req *rqstp)

    {

                  static struct MATH  result;

     

                  /*

                   * insert server code here

                   */

       

        /* 2006/07/04 Dongyy Add -> */

        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;

        }

        /* <- 2006/07/04 Dongyy Add */

     

                  return &result;

    }

    红色字体部分为用rpcgen生成代码后,手动添加的代码。

    添加完后,执行make –f makefile.math 编译生成math_clientmath_server,在命令行运行math_server &,然后运行math_client 127.0.0.1,按照提示输入内容就OK了。

     

    参考书籍《Linux C 高级程序员指南》

  • 相关阅读:
    Win10 蓝屏
    XE Button Color
    IOS 屏幕尺寸
    Delphi 转圈 原型进度条 AniIndicator 及线程配合使用
    Delphi 询问框 汉化
    Delphi Android 询问框
    Delphi BLE 控件
    浮点高低位赋值
    delphi 蓝牙 TBluetoothLE
    16进制字节转换
  • 原文地址:https://www.cnblogs.com/chengliu/p/3636352.html
Copyright © 2020-2023  润新知