1. 通信语义为保证RPC语义的实现,我们必须在两种可能中进行选择。一方面,为尽量使远程过程调用的行为像一个本地过程调用,RPC应该使用一种像TCP这样可靠的运输,而且应该对程序员保证可靠性。另一方面,为允许程序员使用高效率的、无连接的运输协议,远程过程调用机制应当支持用UDP这样的数据报协议进行通信。因为UDP传输的不可靠性,在传输过程中可能因为报文的丢失,使得调用者无法做出应答,而导致远程过程被多次调用。因此,选择UDP作为PRC应用传输协议的程序员,他们所构建的程序必须要能容忍零或多次执行语义。
    在我们下一章的Linux源代码分析中,我们将看到,Linux对于RPC远程过程调用的实现是采用UDP作为它的传输层应用协议来进行的。目前的Linux系统中,并没有采用TCP协议来实现网络文件系统的传输层应用。Linux设计者在这方面的考虑应该是基于实现NFS系统传输的高效性,对于TCP协议的支持相信Linux将会在以后实现。
  2. 通信语义
    在使用TCP或UDP协议进行远程数据传输的时候,需要指定一个服务器的通信端口号。但是,SUN RPC引出了一个有趣的问题:因为它使用32位比特数来标识远程程序,而UDP和TCP运输协议使用16比特数的协议端口号来标识通讯端点,这就有可能超出协议端口的范围。因此,不可能将RPC程序号直接映射到协议端口号,因此RPC不能象其他通讯协议一样使用分配知名端口的协议。但是尽管RPC程序的潜在数量超过了分配知名端口的能力,但RPC和其他服务没有什么不同。在任意给定时间内,单个计算机仅仅执行少量的远程程序。因此,只要端口分配是临时的,每个RPC程序可以获得一个协议端口号,并且使用这个端口号进行通信。
    PRC对于协议端口的获得是通过一个称之为端口映射器的机制来实现的。因为服务器端口映射是临时的,每个 RPC程序在数据传输前可以获得一个协议端口号,并且使用这个传输端口进行通信。
    然而,作为发起远程过程调用的客户机程序,除了知道它所希望与之联系的机器地址以及RPC程序号以外,它还必须在开始执行之后获得一个协议端口,否则不能直接联系远程程序。这种端口映射必须是动态的,因为如果机器重启动或者RPC程序再次开始执行,端口可能会改变。
    ONC RPC机制包含了一个动态映射服务。提供RPC程序的每台机器维护着一个端口映射数据库,而且提供了一种允许调用者将RPC端口号映射为协议端口的机制。它在每台机器中用一个服务器维护这一个小数据库,这个服务器被称为RPC端口映射器。一个RPC程序一旦注册了自己,其他机器上的调用者就可以通过向端口映射器发送一个请求来找到它的协议端口。
  3. 一次RPC远程调用的具体流程
    通过以上两小节的讨论,我们对RPC体系的实现从上到下有了一个概念上的认识。这一小节中,将具体说明一次远程过程调用的具体实现,从而加深对这部分实现机制的认识。
    一个RPC远程过程调用的流程如下:
    1. 需要运行一个远程程序时,本地机器向端口映射器发出注册请求,将一个三元组加到数据库: (RPC程序号,协议端口号,版本号) 并分配给该远程程序一个通信协议端口。
    2. 调用方发送RPC查找请求,调用TCP或UDP协议,将请求报文发送到服务器端口映射器的知名端口,在给定一RPC程序号和版本号时查找其协议端口。
    3. 端口映射器返回这个指定程序当前正在使用的协议端口号。
    4. 调用者在得到了该目标程序正在使用的端口号后,可以直接联系远程程序了。此后,调用方将调用的远程过程的名称、类型、版本号、一些传输的XDR数据结构,进行参数的序列化,构成RPC报文。在调用方和服务器之间实现通信传输。