次の方法で共有


コンテキスト ハンドルを使用したクライアント開発

コンテキスト ハンドルに対してクライアント プログラムが持つ唯一の使用は、クライアントがリモート プロシージャ 呼び出しを行うたびにサーバーに渡すことです。 クライアント アプリケーションは、ハンドルの内容にアクセスする必要はありません。 コンテキスト ハンドル データを何らかの方法で変更しようとしないでください。 クライアントが呼び出すリモート プロシージャは、サーバーのコンテキストで必要なすべての操作を実行します。

サーバーからコンテキスト ハンドルを要求する前に、クライアントはサーバーとのバインドを確立する必要があります。 クライアントは、自動、暗黙的、または明示的なバインディング ハンドルを使用できます。 有効なバインド ハンドルを使用すると、クライアントは、開いている (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);
}