Back to 英特网协议套件

See Also 应用层协议C

Remote Procedure Call

1. WHAT

远程过程调用Remote Procedure Call 简称:RPC)是一个计算机通信协议。该协议允许运行于一台计算机的程序调用另一台计算机的子程序,而程序员无需额外地为这个交互作用编程。如果涉及的软件采用面向对象编程,那么远程过程调用亦可称作远程方法调用

1.1. 历史起源

在网络环境下使用RPC的想法至少可以追溯到20世纪80年代早期ARPANET的文档,由布鲁斯·杰伊·纳尔逊最早创造并使用了这个术语。

第一个把RPC正式商用的程序是由施乐公司在1981年发布的“信使(Courier)” 。1976年以“信使报”的名义使用。RPC首次在UNIX平台上普及的执行工具程序是SUN公司的RPC(现在叫ONC RPC)。它被用作SUN的NFC的主要部件。ONC RPC今天仍在服务器上被广泛使用。另一个早期UNIX平台的工具是“阿波罗”计算机网络计算系统(NCS),它很快就用做OSF的分布计算环境(DCE)中的DCE/RPC的基础,并补充了DCOM。

1.2. 运行方式

远程过程调用是一个分布式计算的客户端-服务器(Client/Server)的例子,它简单而又广受欢迎。远程过程调用总是由客户端对服务器发出一个执行若干过程请求,并用客户端提供的参数。执行结果将返回给客户端。由于存在各式各样的变体和细节差异,对应地派生了各式远程过程调用协议,而且它们并不互相兼容。

1.2.1. RPC通讯过程

  1. 客户端调用客户端存根(client stub):该调用是一个本地过程调用(local procedure call),使用的参数以正常的方式压入堆栈;
  2. 客户存根把参数包装成消息,用一个系统调用来发送消息。包装参数被称为编组(marshalling);
  3. 客户端所在的本地操作系统把消息从客户机发送到服务器的机器;
  4. 服务端操作系统把接到的数据包传递给服务端存根(server stub);
  5. 服务端存根从数据包消息中取出参数。获取参数被称为解组(unmarshalling);
  6. 最后,服务端存根调用服务器程序,服务器响应过程与以上步骤相同。

1.2.2. 标准化的沟通机制

为了允许不同的客户端均能访问服务器,许多标准化的 RPC 系统应运而生了。其中大部分采用接口描述语言(Interface Description Language,IDL),方便跨平台的远程过程调用。

2. WHY

RPC提供了把一个应用程序拆分成多个独立部分的标准方法。

让C程序员掌握RPC是很容易的,通过一些示意代码的演示,更容易在团队中传播多层架构设计理念。

3. ONC/RPC Getting Start

3.1. ONC/RPC规范与实现

RPC (Remote Procedure Call)是一种属于应用层的协议栈,底层为TCP/IP协议;而ONC (Open Network Computing) RPC 是一种被广泛应用的远程过程调用系统。 ONC(开放网络运算(ONC))最早源自于SUN(太阳微系统)公司,是网络文件系统计划的一部份,因此它经常也被称为Sun ONC 或 Sun RPC。

ONC基于调用约定通过C语言应用在Unix系统下。ONC使用 External Data Representation (XDR)进行数据数据系列化;然后通过User Datagram Protocol(UDP协议)或Transmission Control Protocol(TCP协议)传输XDR的数据流(payload)。RPC访问服务通过port mapper 提供,使用端口111(UDP and TCP)。

RFC 1831出版于1995年,描述了ONC RPC的内容;RFC 5531出版于2009年,是现行的版本。至于ONC RPC的认证机制则在 RFC 2695RFC 2203RFC 2623中描述。

3.1.1. RPC Service in difference Platform

Error: Cannot register service: RPC: Unable to receive; errno = Connection refused

# on Centos
sudo yum install rpcbind
sudo service rpcbind start
# on Ubuntu
sudo apt-get install rpcbind
sudo /etc/init.d/rpcbind start
# on Mac OS X
sudo launchctl load -w /System/Library/LaunchDaemons/com.apple.rpcbind.plist

3.2. External Data Representation(XDR)

外部数据表示法(External Data Representation,缩写为XDR)是一种标准的数据序列化格式,用于计算机网络协议。它允许数据在不同的计算机系统之间进行传输。从本地代表转换为XDR称为编码(encoding);从XDR转换为当地的表达方式被称为解码(decoding)。 XDR被作为软件功能库实现,应用于不同的操作系统,同时也独立于传输层。

XDR采用4字节的基本单元,字位顺序由小到大(big-endian);较小的数据类型进行编码后,仍占据4个字节。如字符串等可变长类型会进行填充,使总长度能够被四整除。浮点数使用IEEE 754格式进行表示。

XDR是ONC/RPC的核心;XDR还被应用在其它很多地方,例如HTTP-NG(Refer to RFC 2068)

RFC 4506 2006, Current XDR standard

3.3. RPC Language

RPC语言是一种XDR扩展语言,唯一的扩展是增加了程序的类型。RPC语言与C语言非常像,C程序员学起来会感觉看的都是已经知道的内容。具体参考RPC Programming Guide6. RPC Language.

RPCL语法:

3.3.1. RPC Language Sample

/*
 *  msg.x: Remote msg printing protocol
 *
 *  author liyan(twotwo.li@163.com)
 */
enum actions {Help, Binding, Push, Query};

program MsgRPC {
        version MsgRPC_Ver_1 {
                /* init service */
                int init() = 1;
                /* stop service */
                void stop() = 2;
                string list_actions() = 3;
        } = 1;
} = 0x20002201;

3.4. RPC Compiler

rpcgen是用来生成实现RPC协议的C代码的工具,输入RPC描述文件,生成头文件、XDR结构和服务器与客户端的存根

➜  rpc_sample git:(master) ✗ ll
Makefile
msg.x
msg_proc.c              // Server Process
printmsg.c              // Before Split
rprintmsg.c             // Client
➜  rpc_sample git:(master) ✗ make init
rpcgen -C msg.x         //Generate code in ANSI C style
➜  rpc_sample git:(master) ✗ ll
Makefile
msg.h                   // Gen by RCP Compiler
msg.x
msg_clnt.c              // Gen by RCP Compiler
msg_proc.c
msg_svc.c               // Gen by RCP Compiler
msg_xdr.c               // Gen by RCP Compiler
printmsg.c
rprintmsg.c

3.5. RPC Sample

4. 类似实现

http://en.wikipedia.org/wiki/Remote_procedure_call#Other_RPC_analogues

4.1. Google Protocol Buffers

includes an interface definition language used for its RPC protocols.

4.2. Apache Thrift

4.3. Apache Avro

provides RPC where client and server exchange schemas in the connection handshake and code generation is not required.

5. Reference

MainWiki: RPC (last edited 2013-04-16 00:18:20 by twotwo)