?? rmi
字號:
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 是
“正?!盧MI 調用的結果。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 由指示正?;虍惓7祷氐姆祷卮a、標記返回值的 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://:80/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
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -