參考資料:
rpcgen_mannual PDF可以到Linux公社資源站下載:
------------------------------------------分割線------------------------------------------
免費下載地址在 http://linux.linuxidc.com/
用戶名與密碼都是www.linuxidc.com
具體下載目錄在 /2017年資料/2月/9日/Linux編程之從零開始搭建RPC分布式系統/
下載方法見 http://www.linuxidc.com/Linux/2013-07/87684.htm
------------------------------------------分割線------------------------------------------
cccccc
一、使用rpcgen工具生成RPC底層骨架 1.生成my.x文件,然後在該文件編寫以下程序 首先創建文件夾rpc(mkdir rpc),以後的所有文件都放在這個文件夾下。 創建my.x文件(my為文件名,.x為後綴):vi my.x 在my.x填入下面代碼:#define MY_RPC_PROG_NUM 0x38000010 //程序號 struct my_io_data_s //定義消息結構 { int mtype; int len; char data[1024]; }; typedef struct my_io_data_s my_io_data_t; program MY_RPC_PROG { version MY_RPC_VERS1 { int MY_RPCC(my_io_data_t) = 1; /* 過程號 = 1 */ } = 1; /* Version number = 1 */ version MY_RPC_VERS2 { my_io_data_t MY_RPCC(my_io_data_t) = 1; /* 過稱號 = 1 */ } = 2; /* Version number = 2 */ } = MY_RPC_PROG_NUM; /* Program number */這裡我創建了兩個版本,version1和version2,版本的數量是可以自己定制的,如果你需要一個的話定義一個即可。因為我打算定義一個版本用於SET的操作,一個用於GET操作,所以定義了兩個版本。 上面使用了RPC語言,我對以上幾個特殊名詞做一下解釋。 每個RPC過程由程序號、版本號和過程號來唯一確定。 RPC版本號:程序號標志一組相關的遠程過程,程序號的是有范圍的,我們需要在范圍內填寫程序號。 程序號范圍 簡述 0x00000000 - 0x1FFFFFFF 由Sun公司定義,提供特定服務 0x20000000 - 0x3FFFFFFF 由程序員自己定義,提供本地服務或用於調試 0x40000000 - 0x5FFFFFFF 用於短時間使用的程序,例如回調程序 0x60000000 - 0xFFFFFFFF 保留程序號 這裡我們使用的范圍當然是0x20000000 - 0x3FFFFFFF,我填的是0x38000010。 版本號:在version的大括號裡我們定義兩個我們將要使用的RPC調用函數的類型,比如: version 1:我們定義了int MY_RPCC(my_io_data_t),這表明我們以後PRC框架使用的RPC調用函數的函數類型那個將會是:int * my_rpcc_1(my_io_data_t *argp, CLIENT *clnt) version 2:my_io_data_t MY_RPCC(my_io_data_t) 則會變成 my_io_data_t * my_rpcc_2(my_io_data_t *argp, CLIENT *clnt) 所以我們可以根據我們需要的類型模仿編寫即可。 2.使用rpcgen指令生成以下幾個文件 使用rpcgen my.x生成系列文件(可以加參數-C,表示使用ANSI C) 執行該指令後,文件夾下將出現以下幾個文件。 my.h:
/* * Please do not edit this file. * It was generated using rpcgen. */ #ifndef _MY_H_RPCGEN #define _MY_H_RPCGEN #include <rpc/rpc.h> #ifdef __cplusplus extern "C" { #endif struct my_io_data_s { int mtype; int len; char data[1024]; }; typedef struct my_io_data_s my_io_data_s; typedef my_io_data_s my_io_data_t; #define MY_RPC_PROG 666 #define MY_RPC_VERS1 1 #if defined(__STDC__) || defined(__cplusplus) #define MY_RPCC 1 extern int * my_rpcc_1(my_io_data_t *, CLIENT *); extern int * my_rpcc_1_svc(my_io_data_t *, struct svc_req *); extern int my_rpc_prog_1_freeresult (SVCXPRT *, xdrproc_t, caddr_t); #else /* K&R C */ #define MY_RPCC 1 extern int * my_rpcc_1(); extern int * my_rpcc_1_svc(); extern int my_rpc_prog_1_freeresult (); #endif /* K&R C */ #define MY_RPC_VERS2 2 #if defined(__STDC__) || defined(__cplusplus) extern my_io_data_t * my_rpcc_2(my_io_data_t *, CLIENT *); extern my_io_data_t * my_rpcc_2_svc(my_io_data_t *, struct svc_req *); extern int my_rpc_prog_2_freeresult (SVCXPRT *, xdrproc_t, caddr_t); #else /* K&R C */ extern my_io_data_t * my_rpcc_2(); extern my_io_data_t * my_rpcc_2_svc(); extern int my_rpc_prog_2_freeresult (); #endif /* K&R C */ /* the xdr functions */ #if defined(__STDC__) || defined(__cplusplus) extern bool_t xdr_my_io_data_s (XDR *, my_io_data_s*); extern bool_t xdr_my_io_data_t (XDR *, my_io_data_t*); #else /* K&R C */ extern bool_t xdr_my_io_data_s (); extern bool_t xdr_my_io_data_t (); #endif /* K&R C */ #ifdef __cplusplus } #endif #endif /* !_MY_H_RPCGEN */View Code
my_clnt.c:
/* * Please do not edit this file. * It was generated using rpcgen. */ #include <memory.h> /* for memset */ #include "my.h" /* Default timeout can be changed using clnt_control() */ static struct timeval TIMEOUT = { 25, 0 }; int * my_rpcc_1(my_io_data_t *argp, CLIENT *clnt) { static int clnt_res; memset((char *)&clnt_res, 0, sizeof(clnt_res)); if (clnt_call (clnt, MY_RPCC, (xdrproc_t) xdr_my_io_data_t, (caddr_t) argp, (xdrproc_t) xdr_int, (caddr_t) &clnt_res, TIMEOUT) != RPC_SUCCESS) { return (NULL); } return (&clnt_res); } my_io_data_t * my_rpcc_2(my_io_data_t *argp, CLIENT *clnt) { static my_io_data_t clnt_res; memset((char *)&clnt_res, 0, sizeof(clnt_res)); if (clnt_call (clnt, MY_RPCC, (xdrproc_t) xdr_my_io_data_t, (caddr_t) argp, (xdrproc_t) xdr_my_io_data_t, (caddr_t) &clnt_res, TIMEOUT) != RPC_SUCCESS) { return (NULL); } return (&clnt_res); }View Code
my_svc.c
/* * Please do not edit this file. * It was generated using rpcgen. */ #include "my.h" #include <stdio.h> #include <stdlib.h> #include <rpc/pmap_clnt.h> #include <string.h> #include <memory.h> #include <sys/socket.h> #include <netinet/in.h> #ifndef SIG_PF #define SIG_PF void(*)(int) #endif static void my_rpc_prog_1(struct svc_req *rqstp, register SVCXPRT *transp) { union { my_io_data_t my_rpcc_1_arg; } argument; char *result; xdrproc_t _xdr_argument, _xdr_result; char *(*local)(char *, struct svc_req *); switch (rqstp->rq_proc) { case NULLPROC: (void) svc_sendreply (transp, (xdrproc_t) xdr_void, (char *)NULL); return; case MY_RPCC: _xdr_argument = (xdrproc_t) xdr_my_io_data_t; _xdr_result = (xdrproc_t) xdr_int; local = (char *(*)(char *, struct svc_req *)) my_rpcc_1_svc; break; default: svcerr_noproc (transp); return; } memset ((char *)&argument, 0, sizeof (argument)); if (!svc_getargs (transp, (xdrproc_t) _xdr_argument, (caddr_t) &argument)) { svcerr_decode (transp); return; } result = (*local)((char *)&argument, rqstp); if (result != NULL && !svc_sendreply(transp, (xdrproc_t) _xdr_result, result)) { svcerr_systemerr (transp); } if (!svc_freeargs (transp, (xdrproc_t) _xdr_argument, (caddr_t) &argument)) { fprintf (stderr, "%s", "unable to free arguments"); exit (1); } return; } static void my_rpc_prog_2(struct svc_req *rqstp, register SVCXPRT *transp) { union { my_io_data_t my_rpcc_2_arg; } argument; char *result; xdrproc_t _xdr_argument, _xdr_result; char *(*local)(char *, struct svc_req *); switch (rqstp->rq_proc) { case NULLPROC: (void) svc_sendreply (transp, (xdrproc_t) xdr_void, (char *)NULL); return; case MY_RPCC: _xdr_argument = (xdrproc_t) xdr_my_io_data_t; _xdr_result = (xdrproc_t) xdr_my_io_data_t; local = (char *(*)(char *, struct svc_req *)) my_rpcc_2_svc; break; default: svcerr_noproc (transp); return; } memset ((char *)&argument, 0, sizeof (argument)); if (!svc_getargs (transp, (xdrproc_t) _xdr_argument, (caddr_t) &argument)) { svcerr_decode (transp); return; } result = (*local)((char *)&argument, rqstp); if (result != NULL && !svc_sendreply(transp, (xdrproc_t) _xdr_result, result)) { svcerr_systemerr (transp); } if (!svc_freeargs (transp, (xdrproc_t) _xdr_argument, (caddr_t) &argument)) { fprintf (stderr, "%s", "unable to free arguments"); exit (1); } return; } int main (int argc, char **argv) { register SVCXPRT *transp; pmap_unset (MY_RPC_PROG, MY_RPC_VERS1); pmap_unset (MY_RPC_PROG, MY_RPC_VERS2); transp = svcudp_create(RPC_ANYSOCK); if (transp == NULL) { fprintf (stderr, "%s", "cannot create udp service."); exit(1); } if (!svc_register(transp, MY_RPC_PROG, MY_RPC_VERS1, my_rpc_prog_1, IPPROTO_UDP)) { fprintf (stderr, "%s", "unable to register (MY_RPC_PROG, MY_RPC_VERS1, udp)."); exit(1); } if (!svc_register(transp, MY_RPC_PROG, MY_RPC_VERS2, my_rpc_prog_2, IPPROTO_UDP)) { fprintf (stderr, "%s", "unable to register (MY_RPC_PROG, MY_RPC_VERS2, udp)."); exit(1); } transp = svctcp_create(RPC_ANYSOCK, 0, 0); if (transp == NULL) { fprintf (stderr, "%s", "cannot create tcp service."); exit(1); } if (!svc_register(transp, MY_RPC_PROG, MY_RPC_VERS1, my_rpc_prog_1, IPPROTO_TCP)) { fprintf (stderr, "%s", "unable to register (MY_RPC_PROG, MY_RPC_VERS1, tcp)."); exit(1); } if (!svc_register(transp, MY_RPC_PROG, MY_RPC_VERS2, my_rpc_prog_2, IPPROTO_TCP)) { fprintf (stderr, "%s", "unable to register (MY_RPC_PROG, MY_RPC_VERS2, tcp)."); exit(1); } svc_run (); fprintf (stderr, "%s", "svc_run returned"); exit (1); /* NOTREACHED */ }View Code
my_xdr.c
/* * Please do not edit this file. * It was generated using rpcgen. */ #include "my.h" bool_t xdr_my_io_data_s (XDR *xdrs, my_io_data_s *objp) { register int32_t *buf; int i; if (!xdr_int (xdrs, &objp->mtype)) return FALSE; if (!xdr_int (xdrs, &objp->len)) return FALSE; if (!xdr_vector (xdrs, (char *)objp->data, 1024, sizeof (char), (xdrproc_t) xdr_char)) return FALSE; return TRUE; } bool_t xdr_my_io_data_t (XDR *xdrs, my_io_data_t *objp) { register int32_t *buf; if (!xdr_my_io_data_s (xdrs, objp)) return FALSE; return TRUE; }
更多詳情見請繼續閱讀下一頁的精彩內容: http://www.linuxidc.com/Linux/2017-02/140415p2.htm