컨텍스트 핸들을 사용하여 클라이언트 개발
컨텍스트 핸들에 클라이언트 프로그램이 사용하는 유일한 용도는 클라이언트가 원격 프로시저를 호출할 때마다 서버에 전달하는 것입니다. 클라이언트 애플리케이션은 핸들의 내용에 액세스할 필요가 없습니다. 컨텍스트 핸들 데이터를 어떤 방식으로든 변경하려고 하면 안 됩니다. 클라이언트가 호출하는 원격 프로시저는 서버 컨텍스트에서 필요한 모든 작업을 수행합니다.
서버에서 컨텍스트 핸들을 요청하기 전에 클라이언트는 서버와 바인딩을 설정해야 합니다. 클라이언트는 자동, 암시적 또는 명시적 바인딩 핸들을 사용할 수 있습니다. 유효한 바인딩 핸들을 사용하여 클라이언트는 열린(NULL이 아닌) 컨텍스트 핸들을 반환하거나 원격 프로시저의 매개 변수 목록에서 [out] 매개 변수를 통해 전달되는 서버의 원격 프로시저를 호출할 수 있습니다.
클라이언트는 필요한 방식으로 열린 컨텍스트 핸들을 사용할 수 있습니다. 그러나 더 이상 필요하지 않은 경우 핸들을 무효화해야 합니다. 이 작업을 수행하는 방법에는 두 가지가 있습니다.
- 컨텍스트를 해제하고 컨텍스트 핸들을 닫는 서버 프로그램에서 제공하는 원격 프로시저를 호출하려면( NULL로 설정).
- 서버에 연결할 수 없는 경우 RpcSsDestroyClientContext 함수를 호출합니다.
두 번째 방법은 클라이언트 쪽 상태만 정리하고 서버 쪽 상태를 클린 않으므로 네트워크 파티션이 의심되는 경우에만 사용해야 하며 클라이언트와 서버는 독립적인 정리를 수행합니다. 서버는 런다운 루틴을 통해 독립적인 정리를 수행하며, 클라이언트는 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);
}