无为

无为则可为,无为则至深!

  BlogJava :: 首页 :: 联系 :: 聚合  :: 管理
  190 Posts :: 291 Stories :: 258 Comments :: 0 Trackbacks
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 

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 操作。 

违反协议  
如果出现上述违反协议的现象,或者在具体连接中检测到通讯错误,则多路复用 
连接即被关闭。实际连接将被终止,而所有虚拟连接也被立即关闭。连接的用户 
可以读取虚拟连接中已经可以读取的数据。

凡是有该标志的文章,都是该blog博主Caoer(草儿)原创,凡是索引、收藏
、转载请注明来处和原文作者。非常感谢。

posted on 2005-12-14 13:17 草儿 阅读(139) 评论(0)  编辑  收藏 所属分类: Java编程经验谈

只有注册用户登录后才能发表评论。


网站导航: