版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
第四讲远程过程调用1、动因与实例2、工作原理3、编排/还原4、请求分派内容1、动因与实例2、工作原理
Deposit(1000)
继续运行
启动服务器上的存款过程
intDeposit(number){
returntotal+number;
}
客户端程序
服务器端程序
以对某银行帐户的一个存款过程为例:NetworkLocalCallClientStubRPCInterfaceRPCInterfaceServerStubRemoteProceduresendreceivesendreceive(1)调用过程客户端程序服务器端程序1、客户按本地调用的方式 直接调用本地的客户指代 客户指代具有与服务器相同的过程接口2、客户指代将客户的调用请求进行加工、打包 向底层通信机制(如套接字)发出请求消息 客户指代 不进行任何逻辑处理 只是一个中介3、客户端通过底层的通信机制 将消息传送给服务器端的底层通信机制过程描述:4、服务器需要部分地解析消息 找出客户希望调用的服务器程序5、服务器指代对消息进行解析 从中获得调用者的参数 然后调用服务器程序6、服务器程序执行相应的过程7、服务器程序将结果返回给服务器指代8、服务器指代将结果打包 向底层通信机制发出应答消息9、服务器端通信机制将消息传送给客户端通信机制10、客户端节点上也可能有多个调出点 通信机制需要部分地解析返回的消息 找出消息应该返回给哪个客户程序 并将消息发送给对应的客户指代
11、客户指代从消息中解析结果 返回给客户程序(2)编排/还原(3)请求分派三、基于RPC的开发过程1、定义并编译接口2、编写实现具体服务功能的代码3、编译、连接,产生可执行的服务器程序4、编写客户端代码5、编译、连接,产生客户程序6、运行服务器端程序7、运行客户端程序客户端开发过程服务器端开发过程服务器端程序IDL编译器(rpcgen)客户端程序IDLaccount.haccount_clnt.caccount_svc.cserver.cclient.crpclib.o1、定义并编译接口仍然结合银行帐号的例子 接口定义文件account.x:programACCOUNT{versionACCOUNT_VER{intdeposit(int)=2;intwithdraw(int)=1;}=1;}=0x20010929;编译后生成三个主要文件:
account.h account_clnt.c account_svc.c
extern"C"{#defineACCOUNT0x20010929#defineACCOUNT_VER1#definedeposit2externint*deposit_1(int*,CLIENT*);externint*deposit_1_svc(int*,structsvc_req*);#definewithdraw1externint*withdraw_1(int*,CLIENT*);externint*withdraw_1_svc(int*,structsvc_req*);externintaccount_1_freeresult(SVCXPRT*,xdrproc_t,caddr_t);}account.haccount_clnt.cstaticstructtimevalTIMEOUT={25,0};int*deposit_1(int*argp,CLIENT*clnt){ staticintclnt_res; memset((char*)&clnt_res,0,sizeof(clnt_res)); if(clnt_call(clnt,deposit,(xdrproc_t)xdr_int,(caddr_t)argp,(xdrproc_t)xdr_int,(caddr_t)&clnt_res,TIMEOUT)!=RPC_SUCCESS){ return(NULL); } return(&clnt_res);}int*withdraw_1(int*argp,CLIENT*clnt){ staticintclnt_res; memset((char*)&clnt_res,0,sizeof(clnt_res)); if(clnt_call(clnt,withdraw,(xdrproc_t)xdr_int,(caddr_t)argp, (xdrproc_t)xdr_int,(caddr_t)&clnt_res,TIMEOUT)!=RPC_SUCCESS){ return(NULL); } return(&clnt_res);}intmain(intargc,char**argv){ registerSVCXPRT*transp; pmap_unset(ACCOUNT,ACCOUNT_VER);
transp=svctcp_create(RPC_ANYSOCK,0,0); if(transp==NULL){ fprintf(stderr,"%s","cannotcreatetcpservice."); exit(1); } if(!svc_register(transp,ACCOUNT,ACCOUNT_VER,account_1,IPPROTO_TCP)){ fprintf(stderr,"%s","unabletoregister(ACCOUNT,ACCOUNT_VER,tcp)."); exit(1); }
svc_run();
fprintf(stderr,"%s","svc_runreturned"); exit(1);}account_svc.c
staticvoidaccount_1(structsvc_req*rqstp,registerSVCXPRT*transp){ union{ intdeposit_1_arg; intwithdraw_1_arg; }argument; char*result; xdrproc_t_xdr_argument,_xdr_result; char*(*local)(char*,structsvc_req*); switch(rqstp->rq_proc){ caseNULLPROC: (void)svc_sendreply(transp,(xdrproc_t)xdr_void,(char*)NULL); return; casedeposit: _xdr_argument=(xdrproc_t)xdr_int; _xdr_result=(xdrproc_t)xdr_int; local=(char*(*)(char*,structsvc_req*))deposit_1_svc; break; casewithdraw: _xdr_argument=(xdrproc_t)xdr_int; _xdr_result=(xdrproc_t)xdr_int; local=(char*(*)(char*,structsvc_req*))withdraw_1_svc; break; default: svcerr_noproc(transp); return; } memset((char*)&argument,0,sizeof(argument)); if(!svc_getargs(transp,_xdr_argument,(caddr_t)&argument)){ svcerr_decode(transp); return; } result=(*local)((char*)&argument,rqstp); if(result!=NULL&&!svc_sendreply(transp,_xdr_result,result)){ svcerr_systemerr(transp); } if(!svc_freeargs(transp,_xdr_argument,(caddr_t)&argument)){ fprintf(stderr,"%s","unabletofreearguments"); exit(1); } return;}2、编写实现具体服务功能的代码#include"account.h"inttotal=10000;int*deposit_1_svc(int*argp,structsvc_req*rqstp){staticintresult;
total=total+argp;
result=total;printf(“newtotal=%s”,total);return&result;}int*withdraw_1_svc(int*argp,structsvc_req*rqstp){staticintresult;
total=total-argp;
result=total;printf(“newtotal=%s”,total);return&result;}server.c3、编译、连接,产生可执行的服务器程序cc–oserverserver.caccount_svc.caccount.h4、编写客户端代码#include"account.h"voidaccount_1(char*host){ CLIENT*clnt; int*result_1; intdeposit_1_arg=1000; int*result_2; intwithdraw_1_arg=2000; clnt=clnt_create(host,ACCOUNT,ACCOUNT_VER,"tcp"); result_1=deposit_1(&deposit_1_arg,clnt); printf(“result=%s”,result_1); result_2=withdraw_1(&withdraw_1_arg,clnt); printf(“result=%s”,result_2); clnt_destroy(clnt);}intmain(intargc,char*argv[]){ char*host; if(argc<2){ printf("usage:%sserver_host\n",
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
评论
0/150
提交评论