- 浏览: 151358 次
- 性别:
- 来自: 北京
最新评论
-
pandengzhegt:
好牛!正需要!谢谢了!
JPA 2.0 中的动态类型安全查询 -
yanlp:
万分的感谢。
仿google 的输入提示框 -
huangwenji6111:
可谓良师,在此拜谢!受益匪浅!
hibernate lazy -
jwx0925:
不错!mark!
hibernate对象状态 -
leftstick:
大有裨益,谢了!
hibernate lazy
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://:/ http:///cgi-bin/java-rmi?forward=
第一个 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
10.6 RMI 的多路复用协议
多路复用的目的是提供一种模型,其中两个端点都可打开多个到另一端点的全双
工连接,而在相同环境下,使用其他工具(例如 TCP 连接)时,只有一个端点能
打开这样的双向连接。利用这种简单的多路复用协议,RMI 即可允许客户在某些
其他协议无能为力的情况下,连接到 RMI 的服务器对象上。例如,有些 applet
环境的安全管理器不允许创建服务器套接字监听到来的连接,以防止这种 appl
et 从直接套接字连接上导出 RMI 对象及提供远程调用服务。但是,如果该 app
let 可以打开到其 codebase 主机的正常套接字连接,它就可以在该连接上使用
多路复用协议,从而允许 codebase 主机调用该 applet 所导出的 RMI 对象的方
法。本节介绍了多路复用协议的格式和规则。
10.6.1 定义
本节定义一些将在协议其余部分使用的术语。
端点是用多路复用协议连接的两个用户之一。
多路复用协议必须位于已有的双向可靠字节流之上,假设由一个端点向另一个端
点进行初始化。在当前的 RMI 用法中,它通常是 TCP 连接,由 java.net.Sock
et 对象建立。该连接称为具体连接。
多路复用协议有助于虚拟连接的使用。虚拟连接本身就是双向的可靠字节流,代
表两个端点之间的特定会话。一个连接上两个端点之间的虚拟连接集组成一个多
路复用连接。使用多路复用协议,虚拟连接可以由任一端点打开和关闭。虚拟连
接相对给定端点的状态由在具体连接上发送和接收的多路复用协议元素定义。该
状态涉及连接是打开还是关闭、传送的实际数据及相关的流控制机制。如果没有
特别说明,本节中其余部分将使用术语连接表示虚拟连接。
给定多路复用连接内的虚拟连接由一个 16 位整数标识,称为连接标识符。因而
,一个多路复用连接中可能存在 65,536 个虚拟连接。实现可能会限制能同时使
用的虚拟连接数。
10.6.2 连接状态和流控制
连接由用多路复用协议定义的各种操作来控制。下面是协议所定义的操作名:OP
EN、CLOSE、CLOSEACK、REQUEST 和 TRANSMIT。所有操作的准确格式和规则将在
第 10.6.3 节 “协议格式”中详细介绍。
OPEN、CLOSE 和 CLOSEACK 操作控制连接的打开和关闭,而 REQUEST 和 TRANSM
IT 操作用于在流控制机制的限制内在打开的连接上传输数据。
连接状态
如果端点发送连接的 OPEN 操作或接收到连接的 OPEN 操作(且随后没有关闭它
),则该虚拟连接相对于该端点即为打开的。下面介绍不同的协议操作。
如果端点发送连接的 CLOSE 操作,但随后没有接收到该连接的 CLOSE 或 CLOSE
ACK 操作,则该虚拟连接相对于该端点是等待关闭的。
如果端点从来没有打开过连接或接收到连接的 CLOSE 或 CLOSEACK 操作(且随后
没有打开),则该虚拟连接相对于该端点是关闭的。
流控制
多路复用协议使用简单的包流控制机制允许多个虚拟连接并存于同一具体连接上
。流控制机制的高级要求是所有虚拟连接的状态都是独立的;一个连接的状态不
会影响其他连接。例如,如果处理来自某个连接的数据的数据缓冲区已满,应不
会防碍其他连接的数据传输和处理。如果连接的继续依赖于另一个连接的结束(
例如递归 RMI 调用时),则这一点将至关重要。因而,它的实际意义是实现必须
总能消耗和处理在具体连接上(假定它遵循该规范)准备输入的所有多路复用协
议数据。
每个端点具有两个与各连接相关联的状态值:该端点已经请求但尚未接收到的数
据字节数(输入请求数)和另一端点请求但该端点尚未提供的数据字节数(输出
请求数)。
端点的输出请求数在从其他端点接收到 REQUEST 操作时将增大,而在它发送 TR
ANSMIT 操作时将减小。端点的输入请求数在它发送 REQUEST 操作时将增大,而
在它接收到 TRANSMIT 操作时将减小。这些值如果为负就将违反协议。
如果端点发送 REQUEST 操作而导致其输入请求数增大并超过其当前可以无阻塞处
理的字节数,则违反协议。但如果连接的用户在等待读取数据,则应确保其输入
请求数大于零。
如果端点发送的 TRANSMIT 操作包含有比其输出请求数更多的字节,则违反协议
。它可以缓冲外流的数据,直到连接用户请求显式刷新写入到连接中的数据。但
如果因为显式的刷新或实现的输入缓冲区满而必须在连接上发送数据,则连接用
户可能被阻塞,直到有足够 TRANSMIT 操作。
在满足上述规则的前提下,实现可以相对自由地发送 REQUEST 和 TRANSMIT 操作
。例如,如果其输入缓冲区不空,则端点可以请求连接的更多数据。
10.6.3 协议格式
多路复用协议的字节流格式由连续的可变长度记录序列组成。记录的第一个字节
是一个操作码,它可以识别记录的操作并可确定其内容其余部分的格式。我们定
义了下列合法的操作码:
值 名称
0xE1 OPEN
0xE2 CLOSE
0xE3 CLOSEACK
0xE4 REQUEST
0xE5 TRANSMIT
如果记录的第一个字节不是所定义的操作码,则违反协议。下面各节介绍了每种
操作码的记录格式。
OPEN 操作
下面是 OPEN 操作的记录格式:
大小(字节) 名字 描述
1 opcode 操作码 (OPEN)
2 ID 连接标识符
端点将发送 OPEN 操作以打开指定的连接。如果ID 指向对发送端点当前已打开或
即将关闭的连接,则违反协议。打开连接后,连接的输入和请求数状态在两个端
点上都为零。
接收到 OPEN 操作表示另一端点正在打开指定的连接。打开连接后,连接的输出
和请求数状态在两个端点处都为零。
为防止两端点间的标识符冲突,有效连接标识符空间将根据最高位的值分为两半
。每个端点仅允许打开高位为某一特定值的连接。启动具体连接的端点必须只打
开高位为标识符中的连接,另一端点必须只打开高位为零的连接。例如,如果不
能创建服务器套接字的 RMI applet 启动了与其 codebase 主机的多路复用连接
,则该 applet 可以打开标识符范围为 0x8000-7FFF 的虚拟连接,而服务器可以
打开标识符范围为 0-0x7FFF 的虚拟连接。
CLOSE 操作
以下是 CLOSE 操作的记录格式:
大小(字节) 名字 描述
1 opcode 操作代码 (OPEN)
2 ID 连接标识符
端点发送 CLOSE 操作以关闭指定的连接。如果 ID 指向对发送端点当前已关闭或
即将关闭的连接(如果它已发送过此连接的 CLOSE 操作,也可能是对接收端点即
将关闭的连接),则违反协议。 发送 CLOSE 后,连接就成为对发送端点即将关
闭的连接。因此,该端点将不能重新打开该连接,直到它从另一端点接收到 CLO
SE 或 CLOSEACK 为止。
接收到 CLOSE 操作表示另一端点已关闭指定的连接,因此该连接已在接收端点上
被关闭。虽然接收端点可能不再为此连接发送其它操作(直到被再次打开),但
它仍应为此连接的读者提供实现的输入缓冲区中的数据。如果连接已经被打开(
而不是即将关闭),则接收端点必须用 CLOSEACK 操作作为响应。
CLOSEACK 操作
以下是 CLOSEACK 操作的记录格式:
大小(字节) 名字 描述
1 opcode 操作代码 (OPEN)
2 ID 连接标识符
端点发送 CLOSEACK 操作以表明已收到来自接收端点的 CLOSE 操作。如果收到操
作时 ID 指向的连接不是对接收端点将要关闭的连接,则违反协议。
接收到 CLOSEACK 操作可将指定连接的状态从即将关闭改为已关闭,因此以后还
可重新打开连接。
REQUEST 操作
以下是 REQUEST 操作的记录格式:
大小(字节) 名字 描述
1 opcode 操作代码 (OPEN)
2 ID 连接标识符
4 count 请求的额外字节数
端点发送 REQUEST 操作以增大指定连接的输入请求数。如果 ID 未指向发送端点
打开的连接,则违反协议。端点的输入请求数按值 count 递增。count 的值是
32 位有符号整数。如果为负数或零,则违反协议。
接收到 REQUEST 操作将使指定连接的输出请求数按 count 增加。如果接收端点
即将关闭连接,则将忽略 REQUEST 操作。
TRANSMIT 操作
以下是 TRANSMIT 操作的记录格式。
大小(字节) 名字 描述
1 opcode 操作码 (OPEN)
2 ID 连接标识符
4 count 传输的字节数
count data 传输数据
端点发送 TRANSMIT 操作后,才真正在指定连接上传输数据。如果 ID 未指向对
发送端点打开的连接,则违反协议。端点的输出请求按值 count 递减。count 的
值是 32 位有符号整数。如果为负数或零,则违反协议。如果 TRANSMIT 操作导
致输出请求数成为负数,则也违反协议。
接收到 TRANSMIT 操作时从连接中可读到的字节队列将增加 count 字节的数据。
接收端点的输入请求数按值 count 递减。如果这会使输入请求数成为零,而该连
接的用户却试图读取更多数据,则该端点应用另一个 REQUEST 操作作为响应。如
果接收端点即将关闭连接,则将忽略 TRANSMIT 操作。
违反协议
如果出现上述违反协议的现象,或者在具体连接中检测到通讯错误,则多路复用
连接即被关闭。实际连接将被终止,而所有虚拟连接也被立即关闭。连接的用户
可以读取虚拟连接中已经可以读取的数据。
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://:/ http:///cgi-bin/java-rmi?forward=
第一个 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
10.6 RMI 的多路复用协议
多路复用的目的是提供一种模型,其中两个端点都可打开多个到另一端点的全双
工连接,而在相同环境下,使用其他工具(例如 TCP 连接)时,只有一个端点能
打开这样的双向连接。利用这种简单的多路复用协议,RMI 即可允许客户在某些
其他协议无能为力的情况下,连接到 RMI 的服务器对象上。例如,有些 applet
环境的安全管理器不允许创建服务器套接字监听到来的连接,以防止这种 appl
et 从直接套接字连接上导出 RMI 对象及提供远程调用服务。但是,如果该 app
let 可以打开到其 codebase 主机的正常套接字连接,它就可以在该连接上使用
多路复用协议,从而允许 codebase 主机调用该 applet 所导出的 RMI 对象的方
法。本节介绍了多路复用协议的格式和规则。
10.6.1 定义
本节定义一些将在协议其余部分使用的术语。
端点是用多路复用协议连接的两个用户之一。
多路复用协议必须位于已有的双向可靠字节流之上,假设由一个端点向另一个端
点进行初始化。在当前的 RMI 用法中,它通常是 TCP 连接,由 java.net.Sock
et 对象建立。该连接称为具体连接。
多路复用协议有助于虚拟连接的使用。虚拟连接本身就是双向的可靠字节流,代
表两个端点之间的特定会话。一个连接上两个端点之间的虚拟连接集组成一个多
路复用连接。使用多路复用协议,虚拟连接可以由任一端点打开和关闭。虚拟连
接相对给定端点的状态由在具体连接上发送和接收的多路复用协议元素定义。该
状态涉及连接是打开还是关闭、传送的实际数据及相关的流控制机制。如果没有
特别说明,本节中其余部分将使用术语连接表示虚拟连接。
给定多路复用连接内的虚拟连接由一个 16 位整数标识,称为连接标识符。因而
,一个多路复用连接中可能存在 65,536 个虚拟连接。实现可能会限制能同时使
用的虚拟连接数。
10.6.2 连接状态和流控制
连接由用多路复用协议定义的各种操作来控制。下面是协议所定义的操作名:OP
EN、CLOSE、CLOSEACK、REQUEST 和 TRANSMIT。所有操作的准确格式和规则将在
第 10.6.3 节 “协议格式”中详细介绍。
OPEN、CLOSE 和 CLOSEACK 操作控制连接的打开和关闭,而 REQUEST 和 TRANSM
IT 操作用于在流控制机制的限制内在打开的连接上传输数据。
连接状态
如果端点发送连接的 OPEN 操作或接收到连接的 OPEN 操作(且随后没有关闭它
),则该虚拟连接相对于该端点即为打开的。下面介绍不同的协议操作。
如果端点发送连接的 CLOSE 操作,但随后没有接收到该连接的 CLOSE 或 CLOSE
ACK 操作,则该虚拟连接相对于该端点是等待关闭的。
如果端点从来没有打开过连接或接收到连接的 CLOSE 或 CLOSEACK 操作(且随后
没有打开),则该虚拟连接相对于该端点是关闭的。
流控制
多路复用协议使用简单的包流控制机制允许多个虚拟连接并存于同一具体连接上
。流控制机制的高级要求是所有虚拟连接的状态都是独立的;一个连接的状态不
会影响其他连接。例如,如果处理来自某个连接的数据的数据缓冲区已满,应不
会防碍其他连接的数据传输和处理。如果连接的继续依赖于另一个连接的结束(
例如递归 RMI 调用时),则这一点将至关重要。因而,它的实际意义是实现必须
总能消耗和处理在具体连接上(假定它遵循该规范)准备输入的所有多路复用协
议数据。
每个端点具有两个与各连接相关联的状态值:该端点已经请求但尚未接收到的数
据字节数(输入请求数)和另一端点请求但该端点尚未提供的数据字节数(输出
请求数)。
端点的输出请求数在从其他端点接收到 REQUEST 操作时将增大,而在它发送 TR
ANSMIT 操作时将减小。端点的输入请求数在它发送 REQUEST 操作时将增大,而
在它接收到 TRANSMIT 操作时将减小。这些值如果为负就将违反协议。
如果端点发送 REQUEST 操作而导致其输入请求数增大并超过其当前可以无阻塞处
理的字节数,则违反协议。但如果连接的用户在等待读取数据,则应确保其输入
请求数大于零。
如果端点发送的 TRANSMIT 操作包含有比其输出请求数更多的字节,则违反协议
。它可以缓冲外流的数据,直到连接用户请求显式刷新写入到连接中的数据。但
如果因为显式的刷新或实现的输入缓冲区满而必须在连接上发送数据,则连接用
户可能被阻塞,直到有足够 TRANSMIT 操作。
在满足上述规则的前提下,实现可以相对自由地发送 REQUEST 和 TRANSMIT 操作
。例如,如果其输入缓冲区不空,则端点可以请求连接的更多数据。
10.6.3 协议格式
多路复用协议的字节流格式由连续的可变长度记录序列组成。记录的第一个字节
是一个操作码,它可以识别记录的操作并可确定其内容其余部分的格式。我们定
义了下列合法的操作码:
值 名称
0xE1 OPEN
0xE2 CLOSE
0xE3 CLOSEACK
0xE4 REQUEST
0xE5 TRANSMIT
如果记录的第一个字节不是所定义的操作码,则违反协议。下面各节介绍了每种
操作码的记录格式。
OPEN 操作
下面是 OPEN 操作的记录格式:
大小(字节) 名字 描述
1 opcode 操作码 (OPEN)
2 ID 连接标识符
端点将发送 OPEN 操作以打开指定的连接。如果ID 指向对发送端点当前已打开或
即将关闭的连接,则违反协议。打开连接后,连接的输入和请求数状态在两个端
点上都为零。
接收到 OPEN 操作表示另一端点正在打开指定的连接。打开连接后,连接的输出
和请求数状态在两个端点处都为零。
为防止两端点间的标识符冲突,有效连接标识符空间将根据最高位的值分为两半
。每个端点仅允许打开高位为某一特定值的连接。启动具体连接的端点必须只打
开高位为标识符中的连接,另一端点必须只打开高位为零的连接。例如,如果不
能创建服务器套接字的 RMI applet 启动了与其 codebase 主机的多路复用连接
,则该 applet 可以打开标识符范围为 0x8000-7FFF 的虚拟连接,而服务器可以
打开标识符范围为 0-0x7FFF 的虚拟连接。
CLOSE 操作
以下是 CLOSE 操作的记录格式:
大小(字节) 名字 描述
1 opcode 操作代码 (OPEN)
2 ID 连接标识符
端点发送 CLOSE 操作以关闭指定的连接。如果 ID 指向对发送端点当前已关闭或
即将关闭的连接(如果它已发送过此连接的 CLOSE 操作,也可能是对接收端点即
将关闭的连接),则违反协议。 发送 CLOSE 后,连接就成为对发送端点即将关
闭的连接。因此,该端点将不能重新打开该连接,直到它从另一端点接收到 CLO
SE 或 CLOSEACK 为止。
接收到 CLOSE 操作表示另一端点已关闭指定的连接,因此该连接已在接收端点上
被关闭。虽然接收端点可能不再为此连接发送其它操作(直到被再次打开),但
它仍应为此连接的读者提供实现的输入缓冲区中的数据。如果连接已经被打开(
而不是即将关闭),则接收端点必须用 CLOSEACK 操作作为响应。
CLOSEACK 操作
以下是 CLOSEACK 操作的记录格式:
大小(字节) 名字 描述
1 opcode 操作代码 (OPEN)
2 ID 连接标识符
端点发送 CLOSEACK 操作以表明已收到来自接收端点的 CLOSE 操作。如果收到操
作时 ID 指向的连接不是对接收端点将要关闭的连接,则违反协议。
接收到 CLOSEACK 操作可将指定连接的状态从即将关闭改为已关闭,因此以后还
可重新打开连接。
REQUEST 操作
以下是 REQUEST 操作的记录格式:
大小(字节) 名字 描述
1 opcode 操作代码 (OPEN)
2 ID 连接标识符
4 count 请求的额外字节数
端点发送 REQUEST 操作以增大指定连接的输入请求数。如果 ID 未指向发送端点
打开的连接,则违反协议。端点的输入请求数按值 count 递增。count 的值是
32 位有符号整数。如果为负数或零,则违反协议。
接收到 REQUEST 操作将使指定连接的输出请求数按 count 增加。如果接收端点
即将关闭连接,则将忽略 REQUEST 操作。
TRANSMIT 操作
以下是 TRANSMIT 操作的记录格式。
大小(字节) 名字 描述
1 opcode 操作码 (OPEN)
2 ID 连接标识符
4 count 传输的字节数
count data 传输数据
端点发送 TRANSMIT 操作后,才真正在指定连接上传输数据。如果 ID 未指向对
发送端点打开的连接,则违反协议。端点的输出请求按值 count 递减。count 的
值是 32 位有符号整数。如果为负数或零,则违反协议。如果 TRANSMIT 操作导
致输出请求数成为负数,则也违反协议。
接收到 TRANSMIT 操作时从连接中可读到的字节队列将增加 count 字节的数据。
接收端点的输入请求数按值 count 递减。如果这会使输入请求数成为零,而该连
接的用户却试图读取更多数据,则该端点应用另一个 REQUEST 操作作为响应。如
果接收端点即将关闭连接,则将忽略 TRANSMIT 操作。
违反协议
如果出现上述违反协议的现象,或者在具体连接中检测到通讯错误,则多路复用
连接即被关闭。实际连接将被终止,而所有虚拟连接也被立即关闭。连接的用户
可以读取虚拟连接中已经可以读取的数据。
发表评论
-
java实现Tree
2012-07-10 09:59 876/****************************** ... -
Java正则表达式应用总结
2012-05-25 12:23 1096一、概述 正则表达式是Java处理字符串、文本的重要工具。 ... -
JdbcTemplate与事务
2012-05-17 17:42 1122JdbcTemplate与事务 上例中的JdbcTemplat ... -
Java编程中“为了性能”尽量要做到的一些地方
2012-05-09 17:59 922最近的机器内存又爆满 ... -
jconsole远程监控Java进程
2012-05-07 11:44 1073JDK中的工具jconsole可以很好地监控Java进程及其运 ... -
spring集成quartz
2012-04-16 15:56 2218首先,让spring框架运转起来,可以参看一下:ht ... -
JMX RMI 访问
2011-09-02 10:46 4513RMI(Remote Method Invocation) R ... -
采用开发框架quartz调度管理Job
2011-07-11 10:03 19551.所需要的第三方包:quartz-1.5.2.jarcom ... -
java类型转换
2011-05-20 17:13 912string和int之间的转换? 字符串转换成数据 ... -
java整型数与网络字节序的 byte[] 数组转换关系
2011-05-05 10:47 3778因工作需要在java和c/c++之间进行socket通信,而 ... -
线程安全总结(二)
2010-11-12 10:34 851站内很多人都问我,所谓线程的“工作内存”到底是个什么东西? ... -
java线程安全总结
2010-11-12 10:33 831java线程安全总结(二 ... -
ora-02289问题解决
2010-10-19 12:35 1639<id name="id" type ... -
JDBC的批处理操作三种方式 pstmt.addBatch();
2010-09-25 15:58 8716SQL批处理是JDBC性能优化的重要武器,经本人研究总结,批处 ... -
log4j输出多个自定义日志文件
2010-05-12 10:28 1515<转>http://hi.baidu.com/ ... -
spring任务调度
2010-04-28 09:48 1406概述 在JDK 1.3以后的版本中,Java通过java.ut ... -
JDK线程池的使用
2010-04-07 16:35 1454一、简介 线程池类为 j ... -
Java文件操作
2010-02-06 15:29 873本文汇集常用文件操作方法,包括文件的建立/检查与删除,目录的建 ... -
[JMX一步步来] 6、Model Bean
2009-12-21 11:46 1213在上一节是用apache的commons-modeler来 ... -
[JMX一步步来] 5、用Apache的commons-modeler来辅助开发JMX
2009-12-21 11:45 1079一、前言 每一个MBean都要有一个接口,比如前面的Hello ...
相关推荐
《RMI协议的应用与研究》 远程方法调用(Remote Method Invocation,RMI)是Java平台提供的一种分布式计算技术,它允许Java程序调用运行在不同JVM(Java虚拟机)上的对象的方法,实现了对象的远程透明访问。RMI的...
RMI4,是Synaptics为触控设备设计的一种通信协议,它允许主机系统与触控控制器之间高效地交换数据和控制信息。《511-000136-01-Rev-E-RMI4-Interfacing-Guide.pdf》这份文档深入解析了RMI4协议的各个方面,包括帧...
Java RMI (Remote Method Invocation) 是一种用于在Java应用程序之间进行远程通信的技术。为了提高RMI通信的安全性,我们可以使用SSL (Secure Sockets Layer) 或其后继者TLS (Transport Layer Security) 进行加密。...
此外,还可以使用SSL/TLS等加密协议增强网络通信的安全性。 5. **RMI优化**:为了提高性能,开发者可以使用RMI的优化技术,如单次往返(one-way calls)、远程接口的持久性缓存以及调整RMI的超时和重试策略。 综上...
这些文件分别用于客户端和服务端,以便进行远程通信。 ```bash javac Calculator.java javac CalculatorImpl.java rmic CalculatorImpl ``` 这会生成 `Calculator_stub.class` 和 `Calculator_Skel.class` 文件。 #...
在深入研究RMI时,可以参考给定的文档《IEC-104协议流程.docx》,虽然它与RMI直接关系不大,但了解不同通信协议的流程和机制有助于理解分布式系统中的数据交换过程。IEC-104协议主要用于电力系统自动化设备间的通信...
在这个例子中,我们将深入理解RMI的基本概念、工作原理以及如何创建一个完整的RMI通信系统。 首先,我们要知道RMI的核心思想是将对象的接口和其实现分开,接口在客户端,实现则在服务器端。当客户端调用接口方法时...
2. **RMI (Remote Method Invocation)**:这是一种Java平台上的标准协议,基于JDK的RMI实现,适用于本地或者内网环境,对于简单的RPC调用有一定的优势。 3. **HTTP/HTTPS**:Dubbo支持通过HTTP或HTTPS协议进行通信...
最终将技术选定在了RMI和Java-sockets两种之间,其中RMI的灵活性不高,客户端和服务器端都必须是java编写,但使用比较方便,反观java-sockets,虽然比较灵活,但需要自己规定服务器端和客户端之间的通信协议。...
RMI规范包括了从基础概念到具体实现的多个方面,如分布式对象模型、Stub和Skeleton、客户机和服务器接口、注册服务程序接口、远程对象激活、rmic编译器、分布式垃圾收集器(DGC)以及RMI通信协议。 第一章概述中,RMI...
JAVA分布式之RMI实例教程网络通信原理[收集].pdf
IIOP(Internet Inter-ORB Protocol)是CORBA的一种标准通信协议,使得不同平台的CORBA对象可以通过Internet进行通信。RMI-IIOP使得Java应用可以与非Java的CORBA环境交互。 在"学术测试"这个示例代码中,你可能会...
本文将深入探讨RPC和RMI这两种技术,通过模拟基于.Net平台和Socket通信协议的实现,来具体说明这两种通信机制的工作原理。 远程过程调用(RPC)是一种使客户端能够像调用本地服务一样,透明地调用位于网络中其他...
RMI3是一种专为触摸设备设计的通信协议,它集成了传感器数据处理、I2C或USB接口,并支持多种触控功能,如多点触控、手势识别等。RMI3的主要优势在于其高效的数据传输和强大的功能扩展性,使得设备能够实现更丰富的...
RMI负责处理网络通信和数据序列化,开发者只需关注业务逻辑,无需关心底层网络细节。 这个"java_rmi.rar"压缩包包含的资源可能是一个Java RMI的实例教程或者代码示例。"www.pudn.com.txt"可能是一个包含相关说明...
**RMI原理及应用详解** ...在实际应用中,开发者需要注意RMI的这些特点,并结合实际情况选择是否使用RMI或其他分布式通信技术。通过深入理解和实践,可以充分利用RMI来构建高效、可靠的分布式系统。
在Ehcache RMI Replicated Cluster中,每个节点都持有一份缓存副本,并通过RMI协议实时同步其他节点的更新。这种方式确保了即使在一个节点故障的情况下,其他节点仍然可以继续提供服务,从而实现了高可用性。同时,...
- **通信协议**:RMI使用TCP/IP进行网络通信,通过序列化对象和方法调用信息在客户端与服务器之间传递。 3. **RMI注册表**: - RMI注册表是RMI系统的核心组件,它由`rmiregistry`程序启动。默认情况下,RMI注册表...
- 远程接口:定义了客户端和服务器之间的通信协议。 - 远程对象:实现了远程接口,实际处理远程调用。 - RMI注册表:作为远程对象的服务目录,客户端通过它找到远程对象。 - 远程方法调用:客户端通过接口调用服务器...