參考資料:
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