Stream: Out In
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
StreamProtocol と MultiplexProtocol の場合は、サーバはバイトコード 0x4e で応答してプロトコルをサポートすることを知らせなければならず、そしてホスト名とポート番号を含んだ EndpointIdentifier で応答することによりサーバから見えるところは現在クライアントが使用中であることを知らせます。
クライアントはこの情報を用いて、セキュリティ上の理由でできない場合もありますが、自分のホスト名を知ることができます。
クライアントはその後、もう一個の EndpointIdentifier で応答する必要があり、応答の中には接続を受け付けるときのデフォルトの終点が含まれます。
MultiplexProtocol では、サーバはこの情報からクライアントを特定することが可能です。
StreamProtocol の場合は、エンドポイントのネゴシエーションの後に、 Messages がそれ以上のラッピングを行うことなしに出力ストリームへ送られます。 MultiplexProtocol の場合は、 RMI の多重プロトコルで解説されているようにソケット接続が多重化接続の具体的な接続として使用されます。 この多重化された接続上で開始された仮想接続は、次に説明される一連の Messages から構成されます。
出力タイプには、Call, Ping そして DgcAck の3つのタイプがあります。 Call はメソッド呼び出しをエンコードします。 Ping はトランスポートレベルのメッセージでありリモート仮想マシンが繋がっているかをテストします。 DGCAck はサーバの分散ガベージコレクタへ向けられたメッセージであり、サーバからの返り値に含まれるリモートオブジェクトがクライアントによって受け取られたことを示すアクノレッジ信号です。
Message: Call Ping DgcAck
Call:
0x50 CallData
Ping:
0x52
DgcAck:
0x54 UniqueIdentifier
In: ProtocolAck Returns ProtocolNotSupported HttpReturn
ProtocolAck:
0x4e
ProtocolNotSupported:
0x4f
Returns: Return Returns Return
Return: ReturnData PingAck
ReturnData:
0x51 ReturnValueopt
PingAck:
0x53
CallData: ObjectIdentifier Operation Hash Argumentsopt
ObjectIdentifier: ObjectNumber UniqueIdentifier
UniqueIdentifier: Number Time Count
Arguments: Value Arguments Value
Value: Object Primitive
ReturnValue:0x01UniqueIdentifier Value0x02UniqueIdentifier Exception
write メソッドを使います。(これはオブジェクト直列化が使う writeObject ではありません); それぞれのタイプの識別子の write メソッドはそれぞれのコンポーネントデータを順次出力ストリームへ追加します。
http://<host>:<port>/http://<host>:80/cgi-bin/java-rmi?forward=<port>
HttpPostHeader は POST リクエストのための標準 HTTP ヘッダーです。 HttpResponseHeader はポストへの標準 HTTP 応答です。応答のステータタスが200以外の場合は、Return が無いと判断されます。HTTP POST リクエストに埋め込まれる RMI コールは一つだけであることに注意してください。
HttpMessage: HttpPostHeader Header Message
HttpReturn: HttpResponseHeader Return
CountshortExceptionjava.lang.ExceptionHashlongHostnameStringNumberintObjectjava.lang.ObjectObjectNumberintOperationintPortNumberintPrimitivebyte, int, short, long...Timelong
エンドポイント とは多重プロトコルを使って接続されているユーザの一方を指します。
多重プロトコルはすでに存在する双方向の信頼できるバイトストリームの上位層になり、このバイトストリームはエンドポイントの片側が他方に対して開いたものです。現行の RMI の使用法ではこれは常に java.net.Socket オブジェクトを使って作られた TCP 接続です。この接続のことを具体的接続と呼びます。
多重プロトコルでは仮想接続機能を使うことができ、この接続は双方向の信頼できるバイトストリームであり、2つのエンドポイント間の特定のセッションを表現するものです。 2つのエンドポイント間の一つの具体的接続上の仮想接続のセットが多重接続を構成します。 多重プロトコルを使い、どちらのエンドポイントからも仮想接続のオープンとクローズが可能です。 仮想接続のあるエンドポイントに対しての状態は、具体的接続上でやり取りされる多重プロトコルの要素により定義されます。 この状態は接続のオープン、クローズに関連し、行き来する実際のデータと関連したフローコントロールを含みます。 特別ほかの説明が付加されなければ、接続という用語はこの章の以後の部分では 仮想接続の意味で用いられます。
ある多重接続の中の仮想接続は16ビット整数で特定され、これを 接続識別子と呼びます。したがって、一つの多重接続上には最大65,536の仮想接続が存在することになります。同時に使用できる仮想接続の数は実装によって制限されることがあります。
OPEN, CLOSE, そして CLOSEACK オペレーションは接続の開いたり閉じたりし、REQUEST と TRANSMIT オペレーションは開いた接続上でフローコントロールメカニズムの制限下でのデータ伝送に使われます。
仮想接続はエンドポイントが接続に CLOSE オペレーションを送ったが、まだそれに続く CLOSE または CLOSEACK を受け取っていないときにそのエンドポイントに対して ペンディングクローズの状態にあります。
仮想接続は開かれなかったとき、あるいは CLOSE や CLOSEACK オペレーションを受け取ったときに(そしてそれ以後オープンされていないならば)、その特定のエンドポイントに対して クローズの状態にあります。
各エンドポイントはそれぞれの接続に関して2つの状態値を持ちます。 エンドポイントが何バイトのデータを要求し、そのうちの何バイトがまだ受け取っていないかを示す (入力要求カウント) と、もう一方のエンドポイントが何バイトのデータを要求し、その中でこちらのエンドポイントが何バイトを残しているかを示す (出力要求カウント) です。
一つのエンドポイントの出力要求カウントはもう一方のエンドポイントから REQUEST オペレーションを受けるたびに増加し、TRANSMIT オペレーションを送ると減少します。 一つのエンドポイントの入力要求カウントはそれが REQUEST オペレーションを送ると増加し、TRANSMIT オペレーションを受信すると減少します。どちらかの数値がマイナスになるとプロトコル違反です。
一つのエンドポイントが、ブロッキングの発生なしに現在扱えるバイト数の範囲を超えてて REQUEST オペレーションを送り入力要求カウントを限界を超えて増加させてしまうのはプロトコル違反になります。 しかし、接続されているユーザがデータを待っている状態では、入力要求カウントは確実にゼロ以上の値でなければなりません。 一つのエンドポイントが出力要求カウントを超えた TRANSMIT オペレーションを送るのはプロトコル違反です。 送出されるデータが、その接続のユーザが陽にフラッシュを要求するまで、バッファリングされていることがあります。 フラッシュ要求または、実装の出力バッファフルのためにデータが接続上に送出されるときは、接続上のユーザは十分に TRANSMIT オペレーションが進行するまでブロックされることがあります。
ここで概説した以外では、実装は適切と判断される範囲内で自由に REQUEST や TRANSMIT オペレーションを実行することが出来ます。例えば、エンドポイントは自分の受信バッファが空でなかったとしても接続にたいして追加データを要求することができます。
Value Name ----- ---- 0xE1 OPEN 0xE2 CLOSE 0xE3 CLOSEACK 0xE4 REQUEST 0xE5 TRANSMIT
レコードの最初のバイトが上に定義されたオペレーションコード以外のときはプロトコル違反になります。 次の章でそれぞれのオペレーションコードに対するレコード形式を説明します。
size (bytes) Name Description ------------ ---- ----------- 1 opcode オペレーションコード (OPEN) 2 ID 接続識別子
エンドポイントは OPEN オペレーションを送って指定された接続を開きます。 もし ID が指示する接続がすでにオープンしていたり、送り側のエンドポイントに対してペンディングクローズの状態でこのこのコマンドを送るのはプロトコル違反です。 接続が開かれた状態では両側のエンドポイントでの入力と出力の要求カウントの状態は共にゼロになっています。
OPEN オペレーションの受信は他端のエンドポイントが指定の接続を開こうとしていることを示します。接続がオープンした状態では両側のエンドポイントでの入力と出力の要求カウントの状態は共にゼロになっています。
両側のエンドポイントでの識別子の衝突を防止するために、有効接続識別子のためのスペースは MSB (Most significat bit) の値によって2分されていてます。 それぞれのエンドポイントは高位ビットが特定の値を持っているときだけ接続を開くことが許されます。 具体的接続を開始しようとするエンドポイントは最高位ビットがセット (1)された識別子でのみ接続を開くことができ、他端のエンドポイントは最高位ビットがゼロに設定された識別子で接続を開かなければなりません。 例えば、サーバソケットを作成できない RMI アプレットが自分の codebase ホストに対して多重接続を開始しようとするときは、アプレットは仮想接続を識別子 0x8000-7FFF の範囲で開くことができ、サーバは識別子の範囲 0-0x7FFF の範囲で仮想接続を開くことができます。
Size (bytes) Name Description ------------ ---- ----------- 1 opcode オペレーションコード (OPEN) 2 ID 接続識別子
エンドポイントは CLOSE オペレーションを送って指定の接続を閉じます。 もし、ID が指示する接続が現在閉じていたり、送信側に対してペンディングクローズになっているとプロトコル違反になります(もしこの接続に対して CLOSE オペレーションを送っていると受信側に対してペンディングクローズになっているかもしれません)。 CLOSE を送ると、その接続は送信側のエンドポイントに対してペンディングクローズ状態になります。従って、接続の他端から CLOSE または CLOSEACK を受け取ってからでないと再度接続を開くことはできません。
CLOSE オペレーションの受信は接続の他端がその接続を閉じたことを意味し、受信側にとっても接続は閉じられます。 受信側エンドポイントはこの接続に対してこれ以上の(再度オープンされない限り)オペレーションを行う必要はありませんが、実装の入力バッファにたまっているデータは接続のユーザへ渡さなければなりません。 もし接続がペンディングクローズではなく前もってオープンされているならば、受信側エンドポイントはその接続に対して CLOSEACK で応答する必要があります。
size (bytes) Name Description ------------ ---- ----------- 1 opcode オペレーションコード (OPEN) 2 ID 接続識別子
エンドポイントは受信側エンドポイントからの CLOSE を認識したことを知らせるために CLOSEACK オペレーションを送ります。 もし ID が指定する接続の受信側が、このオペレーションを受信したときにペンディングクローズの状態になっていない場合はプロトコル違反になります。
CLOSEACK オペレーションの受信は、その接続がペンディングクローズからクローズへ状態変化したことを示します。したがって、これ以後はその接続を再オープンすることができます。
size (bytes) Name Description ------------ ---- ----------- 1 opcode オペレーションコード (OPEN) 2 ID 接続識別子 4 count 要求されたバイト数
エンドポイントは REQUEST オペレーションを送ってその接続の入力要求カウントを増加させます。 もし、ID が指定する接続が送信側のエンドポイントから見てオープンされていなければプロトコル違反になります。 エンドポイントの入力要求カウントは countが示す値だけ増加します。 count は符号付きの 32 bit 整数であり、もしこの値がゼロまたはマイナスになるのはプロトコル違反です。
REQUEST オペレーションの受信はその接続の出力要求カウントを countだけ増加させます。 もし受信側にとってその接続がペンディングクローズ状態であるときは、いかなる REQUEST オペレーションも無視されます。
size (bytes) Name Description ------------ ---- ----------- 1 opcode オペレーションコード (OPEN) 2 ID 接続識別子 4 count 伝送バイト数 count data 伝送データ
エンドポイントは TRANSMIT オペレーションにより指定の接続を介して実際のデータ伝送を行います。 もし、指定した接続が送信側のエンドポイントから見てクローズされているときはプロトコル違反になります。 エンドポイントの出力要求カウントは countの値だけ減少します。 count は符号付きの 32 bit 整数であり、送信側の値が TRANSMIT オペレーションによってゼロまたは負の値になるのはプロトコル違反です。
TRANSMIT オペレーションの受信は count バイトのデータがキューに追加され、接続から読める状態になったことを示します。受信側エンドポイントの入力要求カウントは count分だけ減少します。 もし、この結果入力要求カウントがゼロになり、かつ接続のユーザが更にデータを読む必要があるときは、エンドポイントは追加の REQUEST オペレーションで応答しなければなりません。 もし接続が受信側のエンドポイントから見てペンディングクローズならば、いかなる TRANSMIT オペレーションも無視されます。