目次 | 前 の項目 | 次の項目 | Java Remote Method Invocation |
多重化の目的は、エンドポイントの一方だけがほかの機能 (たとえば TCP 接続) を使って双方の接続を開くことができる環境において、2 つのエンドポイントが相互に、他端に対して多重の全二重接続を開くことができるモデルを提供することです。RMI により、この単純な多重化プロトコルを使って、ほかの方法では不可能な状況においても、クライアントが RMI サーバオブジェクトに接続できるようになります。たとえば、アプレット環境のセキュリティマネージャの中には、入ってくる接続を受信するためのサーバソ ケットの作成を禁止して、アプレットが RMI オブジェクトをエクスポートして直接ソケット接続からのリモート呼び出しをサービスできないようにするものがあります。アプレットが codebase ホストへの通常のソケット接続を開くことができる場合には、その接続上で多重プロトコルを使うことにより、そのアプレットがエクスポートした RMI オブジェクトのメソッドを、codebase ホストが呼び出せるようになります。この章では多重プロトコルの形式と規則を説明します。
この章では、後述のプロトコルの説明で使用される用語を定義します。エンドポイントとは、多重プロトコルを使って接続されている二人のユーザの一方を指します。
多重プロトコルは、双方向の、信頼できる既存のバイトストリームの上位層になります。また、このバイトストリームは、エンドポイントの片側が他方に対して 開いたものです。現在の RMI の使用法では、これは常に java.net.Socket オブジェクトを使って作られた TCP 接続です。この接続のことを「具象接続」と呼びます。
多重プロトコルでは、「仮想接続機能」を使うことができます。 仮想接続は、双方向の信頼できるバイトストリームであり、2 つのエンドポイント間の特定のセッションを表現するものです。2 つのエンドポイント間の 1 つの具象接続上の仮想接続のセットが「多重接続」を構成します。多重プロトコルを使って、どちらのエンドポイントからでも仮想接続のオープンとクローズが 行えます。仮想接続のあるエンドポイントに対する状態は、具象接続上でやり取りされる多重プロトコルの要素により定義されます。この状態には、接続のオー プンまたはクローズ、行き来する実際のデータ、および関連するフロー制御機構が含まれます。特にほかの説明がない場合、この章のこれ以降の部分では「接 続」という用語は「仮想接続」の意味で用いられます。
ある多重接続の中の仮想接続は 16 ビット整数で特定され、これを「接続識別子」と呼びます。したがって、1 つの多重接続上には、最大 65,536 の仮想接続が存在することになります。同時に使用できる仮想接続の数は実装によって制限されることがあります。
接続は、種々の多重プロトコルにより定義された「オペレーション」により操作されます。プロトコルで定義されたオペレーションには、OPEN、 CLOSE、CLOSEACK、REQUEST、および TRANSMIT という名前のものがあります。すべてのオペレーションに関する正確な形式と規則の詳細は「10.6.3 プロトコルの形式」に説明されています。OPEN、CLOSE、および CLOSEACK オペレーションは接続を開いたり閉じたりし、REQUEST と TRANSMIT オペレーションは開いた接続上でフロー制御機構の制限下でのデータ伝送に使われます。
仮想接続は、エンドポイントが OPEN オペレーションをその接続に対して送り、その接続に対する OPEN オペレーションを受け取ると (ただし、そのあとにクローズされていない場合)、その特定のエンドポイントに対してオープンした状態になります。種々のプロトコルオペレーションを次に 説明します。仮想接続は、エンドポイントが接続に CLOSE オペレーションを送ったが、まだそれに続く CLOSE または CLOSEACK を受け取っていないときに、そのエンドポイントに対して「ペンディングクローズ」の状態にあります。
仮想接続は開かれなかったとき、あるいは CLOSE や CLOSEACK オペレーションを受け取ったときに(そしてそれ以後オープンされていないならば)、その特定のエンドポイントに対して「クローズ」の状態にあります。
多重プロトコルでは、単純パケットフロー制御機構を使用することにより 1 つの具象接続上に、複数の仮想接続が並行して存在することを認めます。フロー制御機構における高度な要求として、仮想接続の状態はほかから独立していなけ ればならないという要求があります。 つまり、1 つの接続の状態は、ほかの接続に対して影響を及ぼしません。たとえば、接続に入ってくるデータを扱うバッファがいっぱいになったとしても、これがほかの接 続のデータ伝送やデータ処理を妨げることはありません。このことは、1 つの接続の進行が、ほかの接続の使用の終了に依存する場合に必要です。たとえば、RMI の再帰的な呼び出しなどの場合です。したがって、実際問題としては、接続の実装は常にいかなるときでも、具象接続上に多重プロトコルデータ (プロトコル仕様を満たしていると仮定) が入ってくるのに備えている能力がなければなりません。各エンドポイントは、それぞれの接続に関して 2 つの状態値を持ちます。1 つ目の状態値は、エンドポイントが何バイトのデータを要求し、そのうちの何バイトをまだ受け取っていないか (入力要求カウント) を示し、2 つ目の状態値は、エンドポイントが何バイトのデータを要求し、その中でこちらのエンドポイントが何バイトを残しているか (出力要求カウント) を示します。
1 つのエンドポイントの出力要求カウントは、もう一方のエンドポイントから REQUEST オペレーションを受けるたびに増加し、TRANSMIT オペレーションを送ると減少します。1 つのエンドポイントの入力要求カウントは、それが REQUEST オペレーションを送ると増加し、TRANSMIT オペレーションを受信すると減少します。どちらかの数値がマイナスになるとプロトコル違反です。
1 つのエンドポイントが、入力要求カウントを現時点でブロックされることなく処理できるバイト数以上に増加させてしまうほど大きな REQUEST オペレーションを送ることは、プロトコル違反です。しかし、接続しているユーザがデータを読み込むために待機している状態では、入力要求カウントは必ずゼ ロ以上の値でなければなりません。
1 つのエンドポイントが、出力要求カウントを超えた TRANSMIT オペレーションを送るのはプロトコル違反です。送出されるデータが、その接続のユーザが明示的にフラッシュを要求するまで、バッファリングされる可能性が あります。明示的なフラッシュ要求、または実装の出力バッファがいっぱいであるために、その接続を経由してデータを送られなければならない場合は、接続上 のユーザは TRANSMIT オペレーションが十分に進行するまでブロックされる可能性があります。
ここで説明した規則以外でも、適切と判断される範囲内で自由に REQUEST や TRANSMIT オペレーションを実行する実装が可能です。たとえば、エンドポイントは自分の受信バッファが空でなかったとしても接続に対して追加データを要求することが できます。
多重プロトコルのバイトストリーム形式は、可変長レコードが隣接して繋がったものです。レコードの最初のバイトは、オペレーションコードであり、そのレ コードに対するオペレーションを明示し、それ以後の内容の形式を決定します。許されるオペレーションコードは次のとおりです。
値
名前
0xE1
OPEN
0xE2
CLOSE
0xE3
CLOSEACK
0xE4
REQUEST
0xE5
TRANSMIT
レコードの最初のバイトが上に定義されたオペレーションコード以外のときは、プロトコル違反になります。次のセクションでそれぞれのオペレーションコード に対するレコード形式を説明します。
OPEN オペレーションの形式を以下に示します。
サイズ (バイト)
名前
説明
1
opcode
オペレーションコード (OPEN)
2
ID
接続識別子
エンドポイントは、OPEN オペレーションを送ることによって、指定された接続を開きます。ID が指示する接続がすでにオープンしていたり、送り側のエンドポイントに対してペンディングクローズの状態でこのコマンドを送ったりするのは、プロトコル違 反です。接続がオープンされたあとでは、その接続に対する入力および出力の要求カウントの状態は、両側のエンドポイントでゼロになっています。
OPEN オペレーションの受信は、他端のエンドポイントが指定の接続を開こうとしていることを示します。接続がオープンされたあとでは、その接続に対する入力およ び出力の要求カウントの状態は、両側のエンドポイントでゼロになっています。
両側のエンドポイントでの識別子の衝突を防止するために、有効接続識別子のためのスペースは MSB (Most significat bit) の値によって 2 つに分かれています。それぞれのエンドポイントは、高位ビットが特定の値を持っている場合にだけ、接続を開くことが許されます。具象接続を開始しようとす るエンドポイントは、最高位ビットが設定された識別子でだけ接続を開くことができ、他端のエンドポイントは、最高位ビットがゼロに設定された識別子で接続 を開かなければなりません。たとえば、サーバソケットを作成できない RMI アプレットが自分の codebase ホストに対して多重化接続を開始しようとするときは、アプレットは仮想接続を識別子 0x8000-7FFF の範囲で開くことができ、サーバは識別子の範囲 0-0x7FFF の範囲で仮想接続を開くことができます。
CLOSE オペレーションの形式を以下に示します。
サイズ (バイト)
名前
説明
1
opcode
オペレーションコード (OPEN)
2
ID
接続識別子
エンドポイントは、CLOSE オペレーションを送ることによって、指定の接続を閉じます。ID が指示する接続が現在閉じていたり、送信側に対してペンディングクローズになっているとプロトコル違反になります (この接続に対して CLOSE オペレーションを送っていると、受信側に対してペンディングクローズになっている可能性がある)。CLOSE を送ると、その接続は送信側のエンドポイントに対してペンディングクローズ状態になります。したがって、接続の他端から CLOSE または CLOSEACK を受け取ってからでないと、再度接続を開くことはできません。
CLOSE オペレーションの受信は、接続の他端がその接続を閉じたことを意味し、受信側にとっても接続は閉じられます。受信側エンドポイントは、この接続に対してこ れ以上の (再度オープンされない限り) オペレーションを行う必要はありませんが、実装の入力バッファにたまっているデータは、接続のユーザへ渡さなければなりません。接続がペンディングクロー ズではなく前もってオープンされているならば、受信側エンドポイントはその接続に対して CLOSEACK で応答する必要があります。
CLOSEACK オペレーションのレコード形式を以下に示します。
サイズ (バイト)
名前
説明
1
opcode
オペレーションコード (OPEN)
2
ID
接続識別子
エンドポイントは、受信側エンドポイントからの CLOSE を認識したことを知らせるために CLOSEACK オペレーションを送ります。ID が指定する接続の受信側が、このオペレーションを受信したときにペンディングクローズの状態になっていない場合は、プロトコル違反になります。
CLOSEACK オペレーションの受信は、その接続がペンディングクローズからクローズへ状態変化したことを示します。 したがって、これ以後はその接続を再オープンすることができます。
REQUEST オペレーションのレコード形式を以下に示します。
サイズ (バイト)
名前
説明
1
opcode
オペレーションコード (OPEN)
2
ID
接続識別子
4
count
要求された追加バイト数
エンドポイントは、REQUEST オペレーションを送ることによって、その接続の入力要求カウントを増加させます。ID が指定する接続が、送信側のエンドポイントから見てオープンされていない場合は、プロトコル違反になります。エンドポイントの入力要求カウントは、count が示す値だけ増加します。count は、符号付きの 32 bit 整数であり、この値がゼロまたはマイナスになるのは、プロトコル違反です。
REQUEST オペレーションの受信は、その接続の出力要求カウントを count が示す値だけ増加させます。受信側にとってその接続がペンディングクローズ状態であるときは、いかなる REQUEST オペレーションも無視されます。
TRANSMIT オペレーションのレコード形式を以下に示します。
サイズ (バイト)
名前
説明
1
opcode
オペレーションコード (OPEN)
2
ID
接続識別子
4
count
伝送バイト数
count
data
伝送データ
エンドポイントは、TRANSMIT オペレーションにより、指定の接続を介して実際のデータ伝送を行います。指定した接続が、送信側のエンドポイントから見てクローズされている場合は、プロ トコル違反になります。エンドポイントの出力要求カウントは、count の値だけ減少します。count は、符号付きの 32 bit 整数であり、この値がゼロまたはマイナスになるのは、プロトコル違反です。また、TRANSMIT オペレーションで送信側のエンドポイントの出力要求カウントがマイナスになるのも、プロトコル違反です。
TRANSMIT オペレーションの受信は、count バイトのデータがキューに追加され、接続から読める状態になったことを示します。受信側エンドポイントの入力要求カウントは count の値だけ減少します。この結果、入力要求カウントがゼロになり、かつ接続のユーザがさらにデータを読み込む必要がある場合は、エンドポイントは追加の REQUEST オペレーションで応答しなければなりません。接続が受信側のエンドポイントから見てペンディングクローズならば、いかなる TRANSMIT オペレーションも無視されます。
上述したプロトコル違反が発生した場合、または具象接続で通信エラーが発生した場合は、多重接続は「シャットダウン」されます。実際の接続が終了し、すべ ての仮想接続も即時に閉じられます。仮想接続上ですでに読み込み可能になっていたデータは接続のユーザによって読み取り可能です。