发信人: daystream()
整理人: biubiu(2000-01-10 09:24:42), 站内信件
|
RMI 通信协议
10.1 概述
RMI 协议使用另两个协议作为其在通信格式:Java 对象序列化和 HTTP。对象序 列化协议用于编组调用和返回数据。HTTP 协议用于“投寄”远程方法调用,并在 情况允许时获得返回数据。每种协议都有专门的语法文档。产品规则中的非终结 符号可能会引用其它协议(对象序列化或 HTTP)所管理的规则。在跨协议边界时 ,后续产品将使用该嵌入的协议。
关于语法符号的说明
我们使用与 Java 语言规范(参见 JLS 的第 2.3 节)中类似的符号。
流中的控制代码由十六进制形式的文字值表示。
语法中的有些非终结符号表示调用中提供的与应用程序有关的值。这种非终结符 号的定义由其 Java 类型组成。语法后面是将这些非终结字符映射到相应类型的 表。
10.2 RMI 传输协议
RMI 的通信格式由 Stream 表示。这里所采用的术语是从客户机的角度来讲的。 out 指输出消息,而 in 指输入消息。传输标题的内容并未用对象序列化进行格 式化。
Stream: Out In
RMI 所用的输入和输出流是成对出现的。每个 out 流都有相应的 in 流。在语法 中,out 流映射到套接字的输出流(从客户机角度)。in 流(在语法中)将与相 应套接字的输入流配对。由于输出与输入流是成对的,所以输入流中唯一需要的 标题信息就是一个表示是否理解协议的确认;其他标题信息(例如魔数和版本号 )都将由流对的上下文所隐含。
10.2.1 输出流格式
RMI 中的输出流由传输标题信息后跟一个消息序列组成。此外,输出流也可包含 嵌入在 HTTP 协议中的调用。
Out: Header Messages HttpMessage
Header: 0x4a 0x52 0x4d 0x49 Version Protocol
Version: 0x00 0x01
Protocol: StreamProtocol SingleOpProtocol MultiplexProtocol
StreamProtocol: 0x4b
SingleOpProtocol: 0x4c
MultiplexProtocol: 0x4d
Messages: Message Messages Message
Messages 将包装在 Protocol 指定的特定协议内。对于 SingleOpProtocol,He ader 的后面可能只有一个 Message,且该 Message 没有包装其它数据。Single OpProtocol 用于 HTTP 请求中所嵌入的调用,其中请求和响应都只能为一个。
对于 StreamProtocol 和 MultiplexProtocol,服务器必须用字节 0x4e(表示支 持该协议)和 EndpointIdentifier(包含主机名和端口号,服务器可以看到它们 在被客户机使用)进行响应。如果由于安全原因而无法执行该操作,客户机即可 使用该信息来确定其主机名。随后,客户机必须用另一个包含接受连接的缺省端 点的 EndpointIdentifier 进行响应。对于MultiplexProtocol,服务器可以用它 来标识客户机。
对于 StreamProtocol,本次端点协商后,将在输出流上发送 Messages,而不对 数据进行进一步打包。对于 MultiplexProtocol,套接字将连接用作多路复用连 接的具体连接,如第 10.6 节“RMI 的多路复用协议”中所述。在该多路复用连 接上初始化的虚拟连接由一系列 Messages 组成,如下所述。
输出消息共有三种:Call、Ping 和 DgcAck。Call 将对方法调用进行编码。Pin g 是一个传输级消息,用于测试远程虚拟机的活动性。DGCAck 是一个对服务器的 分布式垃圾收集器的确认,指示客户机已经接收到服务器返回值中的远程对象。
Message: Call Ping DgcAck
Call: 0x50 CallData
Ping: 0x52
DgcAck: 0x54 UniqueIdentifier
10.2.2 输入流格式
当前输入信息共有三种:ReturnData、HttpReturn 和 PingAck。ReturnData 是 “正常”RMI 调用的结果。HttpReturn 是 HTTP 协议中嵌入调用的返回结果。P ingAck 是对 Ping 消息的确认。
In: ProtocolAck Returns ProtocolNotSupported HttpReturn
ProtocolAck: 0x4e
ProtocolNotSupported: 0x4f
Returns: Return Returns Return
Return: ReturnData PingAck
ReturnData: 0x51 ReturnValue
PingAck: 0x53
10.3 RMI 对对象序列化协议的使用
RMI 调用中的调用和返回数据将使用 Java 对象序列化协议进行格式化。每个方 法调用的 CallData 表示为 ObjectIdentifier(调用的目标)、Operation(代 表要调用方法的数字)、Hash(检验客户机 stub 与远程对象 skeleton 是否使 用同一 stub 协议的数字),后跟该调用的零个或多个参数列表。
在 JDK1.1 stub 协议中,Operation 代表方法号(由 rmic 分配),而 Hash 是 stub/skeleton 散列,它是该 stub 的接口散列。在 JDK1.2 stub 协议(利用 带 -v1.2 选项的 rmic 生成 JDK1.2 stub)中,Operation 的值为 -1 且 Hash 代表了所要调用方法的散列。散列将在“ RemoteRef 接口”一节中介绍。
CallData: ObjectIdentifier Operation Hash Argumentsopt
ObjectIdentifier: ObjectNumber UniqueIdentifier
UniqueIdentifier: Number Time Count
Arguments: Value Arguments Value
Value: Object Primitive
RMI 调用的 ReturnValue 由指示正常或异常返回的返回代码、标记返回值的 Un iqueIdentifier(用于在必要时发送 DGCAck)后跟以下返回结果组成:返回的值 或抛出的异常。
ReturnValue: 0x01 UniqueIdentifier Valueopt 0x02 UniqueIdentifier Exc eption
---------------------------------------------------------------------- ----------
注意 - ObjectIdentifier、UniqueIdentifier 和 EndpointIdentifier 并不是 用缺省序列化编写的,而是各自使用自己的 write 方法(但不是对象序列化所用 的 writeObject 方法);每种标识符的 write 方法都将其组件数据连续添加到 输出流中。
---------------------------------------------------------------------- ----------
10.3.1 类注解和类加载
RMI 分别覆盖了 ObjectOutputStream 和 ObjectInputStream 的 annotateClas s 和 resolveClass 方法。每个类都用 codebase URL(加载该类的位置)进行注 解。annotateClass 方法中将查询加载该类的类加载器以得到其 codebase URL。 如果类加载器非空且其 codebase 也为非空,则将使用 ObjectOutputStream.wr iteObject 方法将该 codebase 写入流中;否则将使用 writeObject 方法将空值 写入流中。注意:最好不要注解“java”包中的类,因为它们对于接收者来说总 是可用的。
类注解是在序列化恢复期间用 ObjectInputStream.resolveClass 方法解析的。 resolveClass 方法首先用 ObjectInputStream.readObject 方法读取注解。如果 注解(codebase URL)非空,它就获得该 URL 的类加载器并试图加载该类。利用 java.net.URLConnection 获取类字节,即可对该类进行加载(与 web 浏览器的 applet 类加载器所用的机制相同)。
10.4 RMI 对 HTTP POST 协议的使用
为了通过防火墙调用远程方法,有些 RMI 调用使用了 HTTP 协议,尤其是 HTTP POST。在传递标题中指定的 URL 可以为下列内容之一:
http://<host>:<port>/ http://<host>:80/cgi-bin/java-rmi?forward=<port>
第一个 URL 用于与特定 host 和 port 上的 RMI 服务器直接通信。第二种形式 的 URL 用于调用服务器上的“cgi”脚本,后者将把调用转发给指定 port 上的 服务器。
HttpPostHeader 是 POST 请求的标准 HTTP 标题。HttpResponseHeader 是对传 递过程的标准 HTTP 响应。如果响应状态代码不是 200,则认为没有返回值。注 意一个 HTTP POST 请求中只能嵌入一个 RMI 调用。
HttpMessage: HttpPostHeader Header Message
HttpReturn: HttpResponseHeader Return
---------------------------------------------------------------------- ----------
注意 - 只有 SingleOpProtocol 出现在 HttpMessage 的标题中。HttpReturn 不 包含用于确认协议的字节。
---------------------------------------------------------------------- ----------
10.5 RMI 的与应用程序有关的值
本表列表出 RMI 所用的代表与应用程序有关的值的非终结符号。该表将每个符号 映射为相应的类型。每个符号都分别使用它所嵌入在其中的协议进行格式化。
Count short
Exception java.lang.Exception
Hash long
Hostname UTF
Number int
Object java.lang.Object
ObjectNumber long
Operation int
PortNumber int
Primitive byte, int, short, long...
Time long
-- ※ 来源:.月光软件站 http://www.moon-soft.com.[FROM: 202.96.191.124]
|
|