コンテキスト ハンドルを使用したクライアント開発
コンテキスト ハンドルに対してクライアント プログラムが持つ唯一の使用は、クライアントがリモート プロシージャ 呼び出しを行うたびにサーバーに渡すことです。 クライアント アプリケーションは、ハンドルの内容にアクセスする必要はありません。 コンテキスト ハンドル データを何らかの方法で変更しようとしないでください。 クライアントが呼び出すリモート プロシージャは、サーバーのコンテキストで必要なすべての操作を実行します。
サーバーからコンテキスト ハンドルを要求する前に、クライアントはサーバーとのバインドを確立する必要があります。 クライアントは、自動、暗黙的、または明示的なバインディング ハンドルを使用できます。 有効なバインド ハンドルを使用すると、クライアントは、開いている (NULL 以外の) コンテキスト ハンドルを返すか、リモート プロシージャのパラメーター リストの [out] パラメーターを介して 1 つを渡すリモート プロシージャをサーバー上で呼び出すことができます。
クライアントは、必要な方法で開かれたコンテキスト ハンドルを使用できます。 ただし、ハンドルが不要になった場合は、ハンドルを無効にする必要があります。 これを行うには、次の 2 つの方法があります。
- コンテキストを解放し、コンテキスト ハンドルを閉じるサーバー プログラムによって提供されるリモート プロシージャを呼び出すには ( NULL に設定します)。
- サーバーに到達できない場合は、 RpcSsDestroyClientContext 関数を呼び出します。
2 番目の方法では、クライアント側の状態のみがクリーンアップされ、サーバー側の状態がクリーンされないため、ネットワーク パーティションが疑われる場合にのみ使用し、クライアントとサーバーは独立したクリーンアップを実行します。 サーバーはランダウン ルーチンを介して独立したクリーンアップを実行します。クライアントは RpcSsDestroyClientContext 関数を使用してクリーンアップを実行します。
次のコード フラグメントは、クライアントがコンテキスト ハンドルを使用する方法の例を示しています。 この例で使用するインターフェイスの定義を表示するには、「 コンテキスト ハンドルを使用したインターフェイス開発」を参照してください。 サーバーの実装については、「 コンテキスト ハンドルを使用したサーバー開発」を参照してください。
この例では、クライアントは RemoteOpen を呼び出して、有効なデータを含むコンテキスト ハンドルを取得します。 その後、クライアントはリモート プロシージャ呼び出しでコンテキスト ハンドルを使用できます。 バインド ハンドルは不要になったため、クライアントはコンテキスト ハンドルの作成に使用した明示的なハンドルを解放できます。
// cxhndlc.c (fragment of client side application)
printf("Calling the remote procedure RemoteOpen\n");
if (RemoteOpen(&phContext, pszFileName) < 0)
{
printf("Unable to open %s\n", pszFileName);
Shutdown();
exit(2);
}
// Now the context handle also manages the binding.
// The variable hBindingHandle is a valid binding handle.
status = RpcBindingFree(&hBindingHandle);
printf("RpcBindingFree returned 0x%x\n", status);
if (status)
exit(status);
この例のクライアント アプリケーションでは、RemoteRead というプロシージャを使用して、ファイルの末尾が検出されるまでサーバー上のデータ ファイルを読み取ります。 その後、RemoteClose を呼び出してファイルを閉じます。 コンテキスト ハンドルは、RemoteRead 関数と RemoteClose 関数のパラメーターとして次のように表示されます。
printf("Calling the remote procedure RemoteRead\n");
do
{
cbRead = 1024; // Using a 1K buffer
RemoteRead(phContext, pbBuf, &cbRead);
// cbRead contains the number of bytes actually read.
for (int i = 0; i < cbRead; i++)
putchar(*(pbBuf+i));
} while(cbRead);
printf("Calling the remote procedure RemoteClose\n");
if (RemoteClose(&phContext) < 0 )
{
printf("Close failed on %s\n", pszFileName);
exit(2);
}