모든 RPC 클라이언트-서버 프로그램의 중요한 엔티티로는 IDL 파일(인터페이스 정의 파일), 클라이언트 스텁, 서버 스텁 그리고 클라이언트 및 서버 프로그램에서 모두 사용하는 공통 헤더 파일이 포함된다. 클라이언트 및 서버 스텁은 RPC 런타임 라이브러리를 사용하여 통신한다. RPC 런타임 라이브러리는 RPC 애플리케이션을 지원하기 위한 런타임 루틴의 표준 세트를 제공한다. 런타임 루틴 내에서 어떤 일이 어떻게 일어나는지 알면 RPC 프로그래밍에 대해 한 단계 더 높은 수준으로 이해하는 데 도움이 될 것이다.
일반 애플리케이션에서 호출된 프로시저는 같은 주소 공간에서 실행되고 결과는 호출 프로시저로 리턴된다. 다른 시스템에서 작동하는 클라이언트와 서버가 있는 분산 환경을 고려할 때, 클라이언트 측은 서버 측에서 작동하는 프로시저를 호출하고 그 결과가 다시 클라이언트로 전송된다. 이것을 원격 프로시저 호출(RPC)이라고 하며, RPC 프로그래밍의 기초를 이룬다.
RPC 프로그래밍을 사용하는 것은 분산 환경에서 실행 중인 클라이언트 및 서버 애플리케이션 간의 통신을 보장하기 위한 가장 강력하고 효율적인 방법 중 하나다.
그림 1. 기본적인 RPC 클라이언트-서버 상호 작용
그림 1은 클라이언트와 서버가 네트워크를 통해 RPC 호출을 완료하는 방식을 보여준다.
클라이언트 애플리케이션에서 원격 프로시저 호출을 할 때, 그림 1에 나타낸 것처럼 클라이언트 스텁은 양쪽에 있는 RPC 런타임 라이브러리의 도움을 받아 네트워크를 통해 이 호출과 관련된 정보를 서버 스텁으로 전달한다. 서버 스텁은 원격 프로시저 호출이 실행되는 서버 애플리케이션으로 필요한 정보를 제공하고 RPC 런타임 라이브러리를 사용하여 서버 스텁에서 클라이언트 스텁으로 결과를 전달한다. 마지막으로, 클라이언트 스텁은 클라이언트 애플리케이션으로 결과를 다시 리턴한다. 스텁은 양쪽에서 모두 이해할 수 있는 형식으로 애플리케이션과 RPC 런타임 간에 간단히 정보를 교환하는 인터페이스 역할을 한다.
분산 클라이언트-서버 애플리케이션을 개발하는 동안, 클라이언트와 서버는 원격 실행을 위해 상호 간에 교환되는 프로시저의 선언과 정의에 대해 처음부터 합의해야 한다. 이때 인터페이스가 등장하여 클라이언트와 서버가 합의한 모든 프로시저 선언과 데이터 유형을 유지 관리하는 중요한 역할을 하게 된다.
여기서는 클라이언트와 서버가 공유하여 사용할 인터페이스 정의 언어(IDL) 파일에 공통 선언 및 데이터 유형을 모두 포함시킨다. IDL 파일에서 UUID를 사용하여 네트워크 상의 다른 모든 인터페이스 중에서 이 인터페이스를 유일한 것으로 식별할 수 있도록 한다. UUID는 네트워크 주소 정보와 시스템 시간을 사용하는 uuidgen 유틸리티로 생성되는 고유 난수이다.
그림 2는 간단한 클라이언트-서버 분산 애플리케이션을 개발할 때 거치게 되는 다양한 단계를 나타낸 것이다.
그림 2. RPC 클라이언트-서버 애플리케이션 개발
IDL 파일은 헤더 파일 외에 클라이언트 및 서버 스텁 오브젝트 파일을 생성하는 IDL 컴파일러로 컴파일된다. 이 헤더 파일에는 공통의 정의 및 프로시저가 들어 있다. 스텁 파일은 원격 프로시저 호출 중에 애플리케이션과 RPC 런타임 라이브러리 간의 인터페이스 역할을 한다. 헤더 파일은 클라이언트 및 서버 소스 파일에 포함된다. 클라이언트 및 서버 파일은 C 컴파일러로 개별적으로 컴파일되어 오브젝트 파일을 생성한다. 클라이언트 스텁 파일과 함께 클라이언트 오브젝트 파일은 RPC 런타임 라이브러리와 링크되어 클라이언트 실행 파일을 생성한다. 이와 유사하게, 서버 실행 파일은 그림 2에 표시된 것처럼 생성된다.
- 바인딩 정보:
바인딩 정보에는 클라이언트와 서버 간에 사용되는 통신 프로토콜, 서버 네트워크 주소, 서버 프로세스가 실행 중인 엔드포인트(포트 번호)에 대한 정보가 들어 있다.
- 바인딩 벡터:
바인딩 벡터는 바인딩 정보를 참조하는 바인딩 핸들 세트이다.
- 오브젝트 UUID:
인터페이스 세부사항의 관리와는 별도로, 서버 애플리케이션은 오브젝트 UUID라도 하는 자원을 선택적으로 관리할 수도 있다. 인터페이스와 마찬가지로, 서버에서 오브젝트 UUID를 알릴 수도 있다. 클라이언트 애플리케이션은 경우에 따라서 오브젝트 UUID만 선택적으로 가져올 수 있다.
- 시작점 벡터:
RPC 런타임은 해당 프로토콜에 특정한 스위치를 만들도록 프로토콜 ID 테이블을 유지 관리한다. 또한, 프로토콜의 호출, 바인딩, 관리 및 네트워킹 작업과 관련된 프로토콜 서비스 세트를 제공한다. 이들 각각의 서비스가 시작점이 된다. 각각의 시작점 내에는 다시 서비스 가능한 함수 세트가 있다.
- 타워:
바인딩 정보가 이름 서비스 데이터베이스에 저장된 상태의 표현
- 프로토콜 시퀀스:
프로토콜 시퀀스는 RPC 통신에 어떤 네트워크 프로토콜이 사용되는지를 나타낸다. 가장 일반적인 프로토콜 시퀀스는 ncacn_ip_tcp and ncadg_ip_udp이다.
여기서 알 수 있듯이, 각 프로토콜 시퀀스에서는 다음 세 가지 프로토콜이 사용된다.
- NCACN/NCADG – CN(connection) DG(connection less)용 네트워크 통신 아키텍처 프로토콜을 나타낸다.
- IP – 주소 패밀리를 나타낸다.
- TCP/UDP – 전송 계층 프로토콜
그림 3은 클라이언트와 서버 간에 RPC를 완료하기 위한 다양한 단계를 나타낸 것이다.
그림 3. 클라이언트와 서버 간에 RPC를 완료하기 위한 단계
- 서버 RPC 애플리케이션 초기화 중에 RPC 런타임 라이브러리와의 인터페이스를 등록한다. 클라이언트가 서버에 대한 원격 프로시저 호출을 할 때 클라이언트가 서버와 호환되는지 검사하기 때문에, 이런 인터페이스 등록이 필요하다. 서버는 바인딩 정보를 작성하여 클라이언트가 액세스하여 서버에 대한 연결 정보를 찾을 수 있는 이름 서비스 데이터베이스에 바인딩 정보를 저장한다. 서버에서 동적 엔드포인트를 사용하는 경우, 서버는 엔드포인트 정보를 서버 시스템 상의 로컬 엔드포인트 맵 데이터베이스에 저장한다. 로컬 엔드포인트 맵 데이터베이스는 그 호스트에서 실행 중인 RPC 서버 프로세스의 모든 엔드포인트를 저장하는 데 사용된다. 서버는 클라이언트에서 보낸 원격 프로시저 호출을 수신 대기하기 시작한다.
- 클라이언트에서 원격 프로시저 호출을 할 때, 클라이언트는 이름 서비스 데이터베이스에 접속하여 서버 시스템에 대한 정보를 찾는다. RPC 런타임 라이브러리는 이 정보를 이용해 서버 시스템 상의 로컬 엔드포인트 맵 데이터베이스에 접속하여 서버 프로세스가 어떤 엔드포인트에서 RPC를 수신 대기하고 있는지 파악한다.
- 클라이언트가 서버를 찾은 후, 인수를 포함한 원격 프로시저 호출이 클라이언트 스텁에 의해 서버 스텁이 이해할 수 있는 형식으로 변환되고 네트워크를 통해 이를 전송하는 클라이언트 런타임으로 놓는다.
- 서버 RPC 런타임 라이브러리는 이 수신 RPC 호출을 수신하여 서버가 실행을 위해 이해할 수 있는 형식으로 이를 변환하는 서버 스텁으로 전달한다.
- RPC 호출이 실행된 직후, 그 결과는 서버 스텁 및 서버 런타임에 의해 다시 클라이언트에 접속되는 네트워크로 되돌려진다.
- 클라이언트 RPC 런타임이 이를 수신하여 클라이언트 스텁으로 제공하면 클라이언트 스텁이 실행 결과를 클라이언트 프로세스로 전달한다. 클라이언트 애플리케이션은 클라이언트 스텁으로부터 결과를 수신하여 RPC 호출을 완료한다.
본 기사의 나머지 부분에서는 원격 프로시저 호출 실행을 완료하기 위해 클라이언트 및 서버 측에서 위 단계를 각각 수행할 때 사용되는 루틴에 대해 설명한다.
이 섹션에서는 서버 애플리케이션에서 RPC 런타임으로 인터페이스 스펙을 등록하고 이를 이해하는 과정에 대한 개요를 설명한다. rpc_server_register_if
루틴은 등록에 사용되고 rpc_server_unregister_if는 인터페이스 등록 취소에 사용된다.
-
rpc_server_register_if그림 3에 나타낸 것처럼, RPC 서버 애플리케이션이 수행해야 할 첫 단계는 런타임과의 인터페이스를 등록하는 것이다. 이 루틴은 IDL 컴파일러에 의해 생성되는 인터페이스 핸들, 유형 UUID 및 관리자 루틴의 시작점 벡터가 제공되는 경우 같은 결과를 달성하는 데 사용된다.
프로토타입 및 I/O 매개변수:
void rpc_server_register_if(IN rpc_if_handle_t if_spec, IN uuid_p_t mgr_type_uuid, IN rpc_mgr_epv_t mgr_epv, OUT unsigned32 *status);
이 루틴은 우선 NULL 관리자 시작점 벡터인 mgr_epv가 전달되었는지 확인한다. NULL인 경우, 이 루틴은 인터페이스 스펙에 주어진 기본 벡터를 사용한다. 다음으로, 이 루틴은 인터페이스 UUID에 대한 해시 값을 계산하여 UUID의 형식이 유효한지 검사한다. 그런 다음, 인터페이스 레지스트리를 보호하기 위해 잠금을 유지한 후 액세스한다. 이 루틴은 인터페이스 레지스트리 테이블을 통해 해시 검색을 수행하여 요청된 인터페이스 스펙을 시도하고 찾아본다. 검색에 실패하는 경우, 새 인터페이스 항목이 작성되어 레지스트리 테이블에 추가된다. 요청된 인터페이스에 대해 링크된 목록에 삽입되는 참조인 어떤 구조에서 mgr_epv and type_uuid가 채워진다. 지금 이 상태를 인터페이스가 등록되어 있다고 말한다.
이와 유사하게,
rpc_server_unregister_if루틴은 인터페이스 레지스트리 테이블에서 인터페이스를 삭제하는 데 사용된다.
-
rpc_server_use_protseq이 루틴은 지정된 프로토콜 시퀀스를 사용할 것을 RPC 런타임에 알리기 위해 호출된다. 이 루틴은 원하는 NAF(Network Address Family)에 대한 디스크립터를 작성하여 수신 대기 중인 서버 디스크립터의 풀에 추가한다. 이 루틴은 NAF 서비스용 디스크립터에 대해 동적으로 지정되는 이름을 사용한다.
프로토타입 및 I/O 매개변수:
void rpc_server_use_protseq (IN unsigned_char_p_tprotseq, IN unsigned32 max_call_requests,OUT unsigned32 *status);
이 루틴의 Max_calls 입력 매개변수는 특정 프로토콜 시퀀스에 대해 허용되는 최대 동시 호출 수를 표시한다. 이 루틴은 RPC 프로토콜 ID 시퀀스 테이블을 검색하여 주어진 RPC 프로토콜 시퀀스 문자열에 대한 프로토콜 ID를 리턴하는 엔드포인트에 대해 NULL 값을 가진 rpc_server_protseq_ep 루틴을 호출한다. 테이블에서 프로토콜 시퀀스를 찾지 못한 경우, 이 루틴에서 오류를 리턴한다. 그 다음, 이 루틴은 프로토콜 시퀀스 ID, 엔드포인트, NAF ID를 가진 소켓 디스크립터를 작성하여 수신 대기 중인 디스크립터 풀에 추가한다.
-
rpc_server_use_all_protseqs이 루틴은 RPC 런타임에 런타임과 운영 체제에서 모두 지원하는 모든 RPC 프로토콜 시퀀스의 RPC를 수신 대기할 것을 알리는 데 사용된다. 지원되는 각 프로토콜 시퀀스에 대해, 이 루틴은
rpc_server_use_protseq를 호출하여 소켓 디스크립터를 작성하고 이를 수신 대기 중인 디스크립터 풀에 추가한다.프로토타입 및 I/O 매개변수:
void rpc_server_use_all_protseqs(IN unsigned32 max_call_requests, OUT unsigned32 *status);
이 루틴은 우선
rpc_network_inq_protseqs에 대한 호출로 런타임에서 지원하는 유효한 프로토콜 시퀀스 벡터를 얻는다. 지원되는 각 프로토콜 시퀀스에 대해, 이 루틴은rpc_server_use_protseq를 호출하여 서버 소켓 디스크립터를 만들고 이를 수신 대기 중인 디스크립터 풀에 추가한다. 자세한 내용은 rpc_server_use_protseq를 참조한다.다음은 프로토콜 시퀀스 관리에서 중요한 다른 몇 가지 루틴에 대한 설명이다.
- rpc_server_use_all_protseq_if: 이 루틴은 RPC 런타임에 지원되는 모든 프로토콜 시퀀스를 수신 대기하라고 알려주는 데 사용된다. 지원되는 각 protseq에 대해, 지정된 인터페이스 스펙에 잘 알려진 엔드포인트가 있는지 검사한다. 이런 엔드포인트가 있는 경우, rpc_server_use_protseq_ep에 대한 호출로 그 엔드포인트를 바탕으로 소켓을 작성한다.
- rpc_server_use_protseq_if: 이 루틴은 주어진 인터페이스 스펙에 대한 엔드포인트를 조회하고 그것을 바탕으로 소켓을 작성하는 것을 제외하면 rpc_server_use_protseq와 유사하다.
-
rpc_server_inq_bindings이 루틴은 이 서버의 모든 바인딩 정보를 참조하는 서버 바인딩 핸들의 벡터를 얻기 위해 호출된다. 서버 바인딩 핸들 세트를 벡터라고 한다. 이들 핸들은 RPC를 만들 수 있는 핸들이다. 오브젝트 UUID는 이런 바인딩에 속하지 않는다.
프로토타입 및 I/O 매개변수:
void rpc_server_inq_bindings(OUT rpc_binding_vector_t **binding_vector (OUT unsigned32 *status);
이 루틴은 서버 바인딩 핸들 세트를 가져온다. 서버 애플리케이션이 프로토콜 시퀀스 관리에 언급된 루틴 중 어느 것이든 호출할 때 바인딩 핸들이 작성된다. 리턴되는 바인딩 벡터에 잘 알려진 엔드포인트 또는 동적 엔드포인트가 있는 핸들이 포함될 수 있다. 리턴되는 엔드포인트의 유형은 서버 애플리케이션이 프로토콜 시퀀스를 관리하기 위해 호출하는 루틴에 따라 다르다. 바인딩 핸들이 없는 경우, 이 루틴은
rpc_s_no_bindings를 리턴하고 binding_vector 매개변수에서 NULL을 리턴한다.
-
rpc_ns_binding_export서버는 일반적으로 이름 서비스 데이터베이스에서 자신의 인터페이스와 오브젝트 UUID를 공개적으로 알리므로, 어떤 클라이언트 애플리케이션이든 이 정보를 이용해 서버에 연결할 수 있다.
rpc_ns_binding_export호출은 이 정보를 데이터베이스로 내보내는 데 사용된다. 서버가 반드시 이 정보를 데이터베이스로 내보낼 필요는 없으며, 내보내지 않은 경우에는 서버 바인딩 정보를 이미 알고 있는 클라이언트만 서버에 연결할 수 있다.프로토타입 및 I/O 매개변수:
void rpc_ns_binding_export(IN unsigned32 entry_name_syntax,IN unsigned_char_p_t entry_name, IN rpc_if_handle_t if_spec, IN rpc_binding_vector_p_t binding_vector,IN uuid_vector_p_t object_uuid_vector, OUT unsigned32 *status);
이 루틴에서는 한 서버에 대해 여러 개의 바인딩 핸들 또는 오브젝트 UUID를 가진 이름 서비스 데이터베이스 항목을 설정한다. 처음에는, 이 루틴이 if_spec or binding_vec이 NULL인지, object_uuid_vec이 NULL인지 검사한다. NULL인 경우 이 루틴은 rpc_s_nothing_to_export를 리턴한다. 이 루틴은 바인딩 벡터에서 내보낼 NULL이 아닌 바인딩과 NULL이 아닌 UUID의 수도 계수한다. 그런 다음, 바인딩 벡터에서 중복 바인딩을 전부 걸러낸다. 그 다음, 이 루틴은 올바른 항목 이름 구문을 검사하고 런타임 표시에서 이 항목 이름의 이름 서비스 표시를 작성한다. 그런 다음, 네임스페이스에서 이름 서비스 항목을 작성한다. 그리고 인터페이스가 지정되어 있고 NULL이 아닌 각 바인딩을 타워 표시로 변환한 후 내보내기를 수행하는지 검사한다. NULL이 아닌 모든 오브젝트 UUID도 내보낸다.
-
rpc_ns_binding_inq_entry_name이 루틴은 바인딩 핸들이 주어진 상태에서 이름 서비스 데이터베이스에서 이름 서비스 항목을 가져오는 데 사용된다.
프로토타입 및 I/O 매개변수:
void rpc_ns_binding_inq_entry_name(IN rpc_binding_handle_t binding, IN unsigned32 entry_name_syntax, OUT unsigned_char_p_t *entry_name, OUT unsigned32 *status);
이 루틴은 루틴과 함께 전달된 바인딩 핸들이 이름 서비스 데이터베이스에서 항목 이름을 가지고 있는지 검사한다. 항목이 존재하는 경우, 그 항목은 이름 서비스 표시 형식으로 되어 있을 것이다. 이 항목은 런타임 표시에서 항목 이름으로 변환된 후 호출자에게 다시 리턴된다. 데이터베이스에 아무런 항목도 없는 경우, 이 루틴은 rpc_s_no_entry_name 상태 코드를 리턴한다.
-
rpc_ep_register이 루틴은 로컬 엔드포인트 맵 데이터베이스에서 서버의 엔드포인트를 등록하는 데 사용된다. 엔드포인트는 서버가 다시 시작될 때마다 바뀔 수 있으므로, 동적 엔드포인트가 rpc_server_use_protseq 또는 rpc_server_use_all_protseq 루틴에 대한 호출과 함께 사용되는 경우에만 이 루틴이 호출된다. 잘 알려진 엔드포인트가 rpc_server_use_protseq_ep 루틴과 함께 사용되는 경우에도, 클라이언트는 잘 알려진 엔드포인트를 알 필요가 있으므로 서버 애플리케이션은 여전히 엔드포인트를 등록해야 한다. 클라이언트는 인터페이스 스펙을 통해 엔드포인트 값을 얻을 수 있으므로, 잘 알려진 엔드포인트가 rpc_server_use_protseq_if 또는 rpc_server_use_all_protseqs_if에 대한 호출과 함께 사용되는 경우 이 루틴을 호출할 필요가 없다.
프로토타입 및 I/O 매개변수:
void rpc_ep_register(IN rpc_if_handle_t if_spec, IN rpc_binding_vector_p_t binding_vec, IN uuid_vector_p_t object_uuid_vec, IN unsigned_char_p_t annotation, OUT unsigned32 *status);
이 루틴은 우선 인터페이스 핸들이 NULL인지 검사한다. 그래서 NULL인 경우에는 rpc_s_no_interfaces 오류를 리턴한다. 바인딩 벡터가 NULL이거나 벡터에 바인딩이 없는 경우 이 루틴은 rpc_s_no_bindings를 리턴한다. 그 밖에, 이 루틴은 바인딩 벡터 배열을 통과하면서 바인딩 핸들에 대해 NULL이 아닌 포인터를 찾는다. 모든 핸들이 NULL인 경우, 이 루틴은 rpc_s_no_bindings 오류를 리턴한다. 또한, 바인딩 벡터 배열에 엔드포인트가 없는 바인딩 핸들이 있는지 검사하고, 이런 바인딩 핸들을 찾은 경우 rpc_s_invalid_binding 오류를 리턴한다. 엔드포인트가 있는 유효한 바인딩 핸들을 찾았으면, 이 루틴이 로컬 엔드포인트 맵퍼와 대화를 시작하여 데이터베이스에서 엔드포인트를 등록한다.
-
rpc_server_listen이 루틴은 서버가 수신되는 원격 프로시저 호출을 수신 대기하도록 만드는 데 사용된다.
프로토타입 및 I/O 매개변수:
void rpc_server_listen(IN unsigned32 max_calls_exec, OUT unsigned32 *status);
이 루틴은 우선 한 번에 하나의 리스너만 있는지 확인하기 위해 이미 리스너가 있는지 검사한다. 그런 다음, 이 루틴은 서버 소켓 디스크립터가 있는지 검사하고 이들 디스크립터를 리스너에 추가하여 디스크립터를 선택하기 시작한다. 그 다음, 이 루틴은 모든 호출 실행자 스레드를 시작하여 수신되는 RPC를 수신 대기한다. 실행자 스레드에 대한 호출이 RPC 런타임에서 수신되는 RPC를 처리한다. 호출 스레드의 수는 서버에서 처리할 수 있는 최대 동시 RPC 호출 수를 지정하는 입력 매개변수인 max_calls에 따라 다르다. 서버가 최대 개수보다 많이 수신하는 경우, RPC를 실행하기 위해 호출 실행자 스레드를 자유롭게 사용할 수 있을 때까지 추가 RPC를 간단히 큐잉한다. 이 루틴은 누군가 수신 대기를 중지하라고 할 때까지 계속 수신 대기한다. 클라이언트 애플리케이션 또는 서버의 관리자가 rpc_mgmt_stop_server_listening 루틴을 호출할 때 이렇게 할 수 있다. 디스크립터의 테이블에서 서버 소켓을 찾지 못하는 경우, 이 루틴은 rpc_s_no_protseq_registered 오류를 리턴한다.
바인딩 핸들은 대부분의 RPC 런타임 루틴을 위한 기본 입력 매개변수이다. 바인딩 핸들을 사용하여 다른 태스크를 수행할 있고 이들 핸들을 관리해야 하는 것이 필수 사항이 된다. 핸들은 필요에 따라 어떤 오브젝트에 대해 조회하여 완전한 바인딩을 얻고 이를 복사하여 사용할 수 있게 하는 데 사용되는 특정 필드 값에 대해 구문 분석된 문자열 형식으로 변환 및 작성될 수 있다.
(클라이언트 측에서) 이 카테고리로 처리되는 두 가지 중요한 루틴은 다음과 같다.
rpc_binding_to_string_binding rpc_ep_resolve_binding. |
- rpc_binding_to_string_binding
이 루틴은 바인딩 표시 데이터 구조를 읽을 수 있는 문자열 표시로 변환하기 위해 호출된다. 문자열 표시는 일반적으로 다음과 같은 형식으로 되어 있다.
<UUID><Protocol Sequence><Network Address><Endpoint><Network Options>
일반적으로, 애플리케이션은 특정 RPC 서비스의 요구를 충족시키기 위해 사용 중인 프로토콜, IP 주소 및 포트 번호를 알기 위해 이 루틴을 호출한다.
프로토타입 및 I/O 매개변수:
void rpc_binding_to_string_binding (IN rpc_binding_handle_t binding_h, OUT unsigned_char_p_t *string_binding, OUT unsigned32 *status)
이 루틴은 바인딩 핸들을 바인딩 표시가 들어 있는 데이터 구조를 가리키는 입력으로 받는다. UUID, RPC 주소, 엔드포인트 및 네트워크 주소를 옵션으로 검색하기 위한 특정 호출이 이루어진다.
바인딩 표시에 RPC 주소가 들어 있지 않은 경우, 바인딩 시작점을 사용하고 연결과 연관된 RPC 주소를 조회해야 한다. RPC 주소에 대한 참조를 포함한 네트워크 주소 시작점은 네트워크 주소, 엔드포인트 및 네트워크 옵션 세부사항을 페치하는 데 사용된다.
프로토콜 시퀀스 테이블에서 프로토콜 시퀀스가 검색된다. 이 테이블에는 다른 NAF 및 RPC 지원 프로토콜에 대한 ID가 들어 있다.
그런 다음, 위의 모든 데이터는 하나의 전체 문자열에서 구성되고 호출자로 리턴된다. rpc_string_binding_composeroutine이 같은 작업을 수행하는 데 사용된다.
반대로, 바인딩의 문자열 표시를 바인딩 핸들로 변환하는 루틴도 있다.
- rpc_ep_resolve_binding
이 루틴은 부분적으로 바인드된 바인딩 핸들을 확인하기 위해 호출된다. 네트워크 주소 파트만 있고 아직 엔드포인트를 가져와야 하는 바인딩 핸들을 부분적으로 바인드되어 있다고 한다. RPC 디먼은 주어진 인터페이스 및 오브젝트 UUID에 대한 엔드포인트 정보가 들어 있는 엔드포인트 맵을 유지 관리한다. RPC 런타임은 이 디먼에 접속하여 엔드포인트 정보를 검색해 호출자에게 리턴한다.
프로토타입 및 I/O 매개변수:
>void rpc_ep_resolve_binding(IN rpc_binding_handle_t binding_h, IN rpc_if_handle_t if_spec_h, OUT unsigned32 *status);
이 루틴의 핵심적인 부분은 바인딩 핸들 표시에 엔드포인트가 없는 경우 엔드포인트를 결정하는 데 있다. 그 밖에, 이 루틴은 rpc_s_ok 상태를 호출자에게 간단히 리턴한다. RPC 디먼이 쿼리되고, 첫째로 주어진 인터페이스에서 가져올 한 엔드포인트가 시도된다. RPC 디먼이 엔드포인트를 하나 찾은 경우, 이 엔드포인트가 바인딩에 추가되고 바인딩 벡터 시작점이 바인딩 정보의 변경 내용에 대해 프로토콜 서비스에 알려주고 엔드포인트를 호출자에게 리턴한다.
인터페이스에 엔드포인트가 없는 경우에는 인터페이스에서 지정된 주소에 있는 엔드포인트 데이터베이스에 접속하기 위한 RPC 호출이 이루어진다. 이를 수행하기 전, 런타임은 통신 제한시간 값이 무한 대기로 설정되어 있지 않음을 확인한다. 무한 대기로 설정되어 있는 경우에는 런타임이 이를 최대 제한시간 값으로 설정한다. 이는 런타임이 엔드포인트 데이터베이스에 대해 영원히 시도할 필요가 없기 때문이다. 또한, 런타임은 엔드포인트 데이터베이스를 인스턴스화하기 위해 오브젝트 UUID가 NULL임을 확인한다. 엔드포인트 데이터베이스에 접속하기 위해 완전히 바인드된 핸들이 있으면, 주어진 인터페이스의 프로토콜 버전이 서버 인터페이스의 프로토콜 버전과 호환되는지 검사한다. 그 밖에는, RPC 디먼이 엔드포인트를 리턴하지 않는다.
늘 그렇듯이, 바인딩 벡터 시작점이 바인딩 핸들의 변경 내용에 대해 프로토콜 서비스에 알려준다. 다음 태스크는 엔드포인트 데이터베이스에서 주어진 인터페이스에 대해 호환되는 타워를 모두 찾는 것이다. 이 작업을 수행하기 위해, 클라이언트는 검색 키 역할을 하는 맵 타워의 형태로 데이터를 제공한다. 맵 타워는 주어진 인터페이스 스펙에서 생성되고 주로 인터페이스 UUID, 버전, 프로토콜 시퀀스, 프로토콜 버전 등으로 구성된다. 엔드포인트 데이터베이스를 검색할 때 이 맵 타워가 키로 사용되고 모든 호환 타워의 목록을 얻을 수 있다. 그런 다음, 임의로 선택한 호환 타워가 엔드포인트가 추출되는 RPC 주소로 변환된다. 이 엔드포인트는 주어진 인터페이스의 바인딩 핸들에 추가되고 호출자에게 리턴된다.
이름 서버 데이터베이스는 바인딩 정보로 표시되는 서버 위치 정보의 저장소이다. 클라이언트 애플리케이션은 일반적으로 다음과 같은 목적으로 특정 이름 서비스 RPC 루틴을 사용한다.
- 데이터베이스에 대한 참조 가져오기
- 호환 가능한 바인딩 목록 가져오기
- 바인딩 조회 또는 검색
- 바인딩 선택
- 검색 표시 및 완료된 것으로 검색
- rpc_ns_binding_import_begin
일반적으로, RPC 서버 애플리케이션은 그 위치를 알리거나 내보내는데, 이는 이름 서비스 데이터베이스에 저장되는 바인딩 정보이다. 클라이언트는 이 데이터베이스에 연결하여 서버의 위치를 파악한다. 클라이언트 애플리케이션은 rpc_ns_binding_import_begin 루틴을 사용하여 이름 서비스 데이터베이스의 바인딩 정보를 검색하는 데 사용되는 참조를 얻는다.
프로토타입 및 I/O 매개변수:
void rpc_ns_binding_import_begin (IN unsigned32 entry_name_syntax IN unsigned_char_p_t entry_name, IN rpc_if_handle_t if_spec, IN uuid_p_t object_uuid, OUT rpc_ns_handle_t *import_context, OUT unsigned32 *status);
첫 번째 매개변수인
entry_name_syntax는entry_name이 입력되는 방식을 지정하는 정수 값이다.entry_name은 시작할 검색 문자열의 이름이다. 인터페이스와 선택적으로 오브젝트 UUID에 대한 핸들도 지정된다.이 루틴은 필요한 초기화를 수행하는 rpc_ns_binding_lookup_begin을 호출한다. 항목 이름 구문과 항목 이름이 NULL로 전달되는지 검사하기 위한 매크로가 호출된다. NULL로 전달되는 경우에는 기본값이 사용된다.
entry_name과 구문으로 구성되는 이름 서비스 항목 표시 구조에 대한 메모리가 할당된다. 그런 다음, 항목 이름은 완전한 DNS 이름으로 확장되어 리턴된다. 그 다음으로 연결 목록인 검색 데이터 구조가 초기화된다. 이 구조의 중요한 필드는 인터페이스 스펙 이름 서비스 캐시를 새로 고쳐야 할지 파악하기 위한 캐시의 만기이다. 검색 노드가 작성 및 초기화되는데, 역시 이름 서비스 항목을 가지고 있다. 이 노드가 검색 목록의 시작 부분에 추가되고 이 노드에 대한 참조가 가져오기 컨텍스트로 리턴된다. 클라이언트 애플리케이션은 이제 이 가져오기 컨텍스트를 사용하여 이름 서비스 데이터베이스에서 바인딩 정보를 가져올 수 있다.
- rpc_ns_binding_import_next
검색 구조에 대한 참조를 import_context로 가져온 경우, 클라이언트 애플리케이션은 이 루틴을 사용하여 주어진 인터페이스에 대해 호환 가능한 바인딩 정보를 가져올 수 있다. 오브젝트 UUID 사용은 선택사항이다.
프로토타입 및 I/O 매개변수:
void rpc_ns_binding_import_next ( [in] rpc_ns_handle_t import_context, [out] rpc_binding_handle_t *binding, [out] unsigned32 *status);
첫 번째 태스크는 주어진 네임스페이스 항목에 대해 호환 가능한 바인딩을 검색하는 것이다. 이를 위해 호환 가능한 모든 바인딩으로 구성된 바인딩 벡터를 가져와야 한다. rpc_ns_binding_lookup_next 루틴을 호출하면 이 바인딩 벡터를 가져올 수 있다. 이 루틴 내에서, 우선 NULL이 아닌 컨텍스트 핸들이 있는지에 대한 검사가 이루어진다. 이 컨텍스트 핸들에는 이름 서버 데이터베이스에서 검색을 수행하는 데 사용되는 참조가 있다. 바인딩 벡터를 위한 메모리가 할당 및 초기화된다. 그런 다음, 루프로 들어가서 첫 번째 노드를 검색하고 노드 해결을 시도한다. 여기서 노드 해결이란, 호환 가능한 바인딩의 전체 목록을 가져오거나 노드 목록에 유효한 멤버를 추가하는 것을 의미한다. 해결 유형은 네임스페이스 항목의 유형에 따라 다르다. 이 경우, 해결 유형은 호환 가능한 바인딩을 검색하는 것이거나 컨텍스트가 추가해야 하는 그룹 프로파일 항목으로 구성되는 것이 될 수 있다. 이름 서버 데이터베이스의 바인딩 정보는 타워라고 하는 데이터 구조에 저장된다.
그림 4. 간단한 타워 표시
타워의 프로토콜 시퀀스, 인터페이스 ID, 전송 구문 및 프로토콜 버전 번호가 클라이언트 인터페이스의 해당 정보와 일치할 때 호환 가능한 바인딩을 찾았다고 할 수 있다. 해결 후 리턴되는 상태 코드에 따라, rpc_ns_binding_import_next 내에서 케이스가 처리된다. rpc_ns_binding_lookup_next 루틴은 바인딩 벡터가 가득 차 있거나 호환 가능한 바인딩이 있는지 모든 노드를 검색했는지 여부를 리턴한다. 바인딩 벡터가 미리 정의된 값에 도달하면 바인딩 벡터가 가득 찬 것으로 간주한다. rpc_ns_binding_lookup_next에서 돌아온 후, 벡터에서 호환 가능한 바인딩을 임의로 선택하기 위한 호출이 이루어지고 호출자에게 리턴된다.
클라이언트 애플리케이션은 RPC 런타임에서 제공하는 다음 루틴을 사용하여 인터페이스 세부사항을 쿼리한다.
- rpc_if_inq_id
이 루틴은 인터페이스의 ID와 인터페이스 UUID의 주 버전 또는 부 버전에 대한 조회를 위해 호출된다. 이 데이터가 필요한 상황은 거의 없지만, 인터페이스 및 타워 ID를 비교할 때, 이름 서비스 데이터베이스에서 여러 바인딩을 제거할 때 등에 필요하다.
프로토타입 및 I/O 매개변수:
void rpc_if_inq_id(IN rpc_if_handle_t if_spec, OUT rpc_if_id_t *if_id, OUT unsigned32 *status);
이 기능은 인터페이스 표시 구조(if_spec)에서 인터페이스의 UUID와 버전을 검색하고 이 정보를 인터페이스 ID 구조(if_id)에 채우기 위한 간단한 프로시저이다. 이 구조는 인터페이스의 UUID, 주 버전 및 부 버전이 필드로서 구성되어 있다. if_spec에서 검색한 버전 번호는 32비트 번호로서, 0xffff로 AND 연산 처리되어 주 버전을 가져오고 오른쪽으로 16회 시프트되어 부 버전을 가져온다. 이 모든 정보가 if_id에 채워지고 그 참조가 호출자에게 리턴된다.
- rpc_if_id_vector_free
이 루틴은 애플리케이션의 종료 핸들러 또는 정리 루틴의 일부로 호출될 수 있다.
프로토타입 및 I/O 매개변수:
void rpc_if_id_vector_free (IN/OUT rpc_if_id_vector_p_t *if_id_vector, >OUT unsigned32 *status);
이것은 런타임이 인터페이스 ID 벡터 구조에 할당한 메모리를 사용 가능하게 하기 위한 간단한 프로시저이다. 이 구조는 인터페이스 ID 구조에 대한 포인터와 그런 인터페이스의 개수로 이루어진다. 입력 벡터 자체가 처음에 NULL인 경우에는 rpc_s_invalid_arg 상태가 리턴된다. 그 밖에, 이 벡터에 대한 탐색이 이루어져 각 인터페이스를 위해 사용 가능한 메모리가 늘어난다. 마지막으로, 벡터에 할당된 메모리 역시 사용 가능하게 되고 NULL 벡터가 호출자에게 리턴된다.
- rpc_network_inq_protseqs
주어진 호스트에서 지원되는 모든 프로토콜 시퀀스의 벡터를 알면 애플리케이션 및 런타임 레벨 결정에 도움이 된다. 예를 들어, RPC 런타임이 호스트에서 지원하는 유효한 프로토콜 시퀀스에서만 수신 대기하는 것이 논리적일 것이다. 또는 RPC 애플리케이션에서 단순히 호스트에서 지원하는 프로토콜 시퀀스를 쿼리만 할 수도 있다. 그런 경우에 이 루틴이 호출된다.
프로토타입 및 I/O 매개변수:
void rpc_network_inq_protseqs(OUT rpc_protseq_vector_p_t *protseq_vector, OUT unsigned32 *status)
첫 번째로 이루어지는 검사는 프로토콜 시퀀스 개수가 0인지 확인하는 것이다. 0인 경우, 이 루틴은 간단히 프로토콜 시퀀스가 없다는 메시지를 리턴한다. 또는 프로토콜 시퀀스의 문자열을 유지하기 위해 필요한 메모리가 할당된다. 그런 다음, 프로토콜 시퀀스 ID 테이블에 대한 탐색이 이루어지고 프로토콜 문자열이 출력 매개변수 'protseq_vector'로 복사된다.
- rpc_network_is_protseq_valid
RPC 애플리케이션은 호스트에서 특정 프로토콜 시퀀스가 지원되는지 확인한 후 프로토콜을 계속 사용하려고 할 수 있다. 그런 경우, rpc_network_is_protseq_valid가 프로토콜 시퀀스 문자열과 함께 입력으로 호출된다. 이 루틴이 호출된 후 rpc_server_use_protseq를 호출하는 것이 가장 일반적이다.
프로토타입 및 I/O 매개변수:
boolean rpc_network_is_protseq_valid( IN unsigned_char_p_t protseq, OUT unsigned32 *status)
이 루틴은 주어진 입력 문자열에 대해 프로토콜 시퀀스 ID 테이블을 검색한다. 찾지 못한 경우에는 rpc_s_protseq_not_supported가 리턴된다. 프로토콜 시퀀스 ID 테이블은 주어진 프로토콜 시퀀스가 지원되는지 여부를 나타내기 위한 부울 필드로 구성된다. 이 필드는 런타임의 초기화 중에 채워진다. 이 방법에는 테이블을 탐색하여 네트워크 주소 패밀리, 인터페이스 및 프로토콜을 가져오는 과정이 포함된다. 이 3개의 매개변수는 운영 체제에서 소켓을 여는 데 사용되고, 성공한 경우 이는 프로토콜에서 지원하는 필드가 TRUE로 설정되어 있다는 뜻이다.
rpc_network_is_protseq_valid()의 호출자에게 같은 값이 리턴된다. FALSE인 경우, 상태 필드는 rpc_s_protseq_not_supported로 설정된다. 주어진 프로토콜 시퀀스 문자열에 대해 일치하는 항목을 찾지 못한 경우에는 상태 필드가 rpc_s_invalid_rpc_protseq로 설정된다.
- rpc_mgmt_ep_elt_inq_begin
RPC 애플리케이션에서 엔드포인트의 내용을 보려고 할 때, 이 애플리케이션은 우선 엔드포인트에 액세스하기 위한 참조를 가져와야 한다. 그런 경우에 이 루틴이 호출된다.
프로토타입 및 I/O 매개변수:
void rpc_mgmt_ep_elt_inq_begin (IN rpc_binding_handle_t input_binding, IN unsigned32 inquiry_type, IN rpc_if_id_p_t if_id, IN unsigned32 vers_option, IN uuid_p_t object_uuid,OUT rpc_ep_inq_handle_t *inquiry_context, OUT unsigned32 *status);
이 루틴에서는 로컬 또는 원격 엔드포인트에 액세스하기 위해 사용할 수 있는 조회 컨텍스트를 작성한다. 이 컨텍스트를 가져오려면, 우선 입력 바인딩 매개변수에서 지정한 것처럼 로컬 또는 원격 호스트에서 엔드포인트에 바인드해야 한다. 전달된 매개변수가 NULL인 경우에는 런타임이 지원되는 프로토콜 시퀀스 중 하나로 로컬 엔드포인트에 바인드한다. 그 후, 문자열 바인딩이 바인딩 핸들로 변환된다. 입력 바인딩 매개변수가 NULL이 아닌 경우에는 엔드포인트가 원격 호스트에 있다는 뜻이다. RPC 주소와 프로토콜 버전, 제한시간 등의 다른 바인딩 데이터 구조의 필드 값은 모두 이 입력 바인딩 핸들에서 검색되어 다른 핸들 표시로 복사된다. rpc_binding_copy 루틴이 이 태스크를 수행한다. 여기서는 엔드포인트 데이터베이스에 대한 참조를 간단히 가져오는 것이 목적이다. 그래서 rpc_binding_copy에서 가져온 새 핸들이 있으면, RPC 주소에 연결된 엔드포인트가 지워진다. 따라서 가져온 핸들이 엔드포인트 조회 컨텍스트 구조의 적당한 필드로 복사된다. 이 구조에는 특히 조회 유형, 오브젝트 UUID, 인터페이스 ID와 같은 다른 필드도 있다. 모든 구조 필드가 적절히 채워지고 이 구조에 대한 참조가 호출자에게 inquiry_context로 리턴된다.
- rpc_mgmt_ep_elt_inq_next
이 루틴은 엔드포인트 데이터베이스의 내용을 보기 위해 호출된다. 일반적으로, 엔드포인트 데이터베이스의 내용은 UUID, 인터페이스 ID, 어노테이션 표시 및 문자열 바인딩 정보로 구성된 세트이다.
프로토타입 및 I/O 매개변수:
void rpc_mgmt_ep_elt_inq_next (IN rpc_ep_inq_handle_t inquiry_context, OUT rpc_if_id_t *if_id, OUT rpc_binding_handle_t *binding, OUT uuid_t *object_uuid, OUT unsigned_char_p_t *annotation, OUT unsigned32 *status);
rpc_mgmt_ep_elt_inq_begin 루틴에서 가져온 조회 컨텍스트 참조를 이용해 엔드포인트 데이터베이스에 대한 액세스가 이루어진다. 이름 서비스 데이터베이스에서와 같이, 엔드포인트 데이터베이스에서도 정보가 타워 표시에 저장된다. 검색된 각각의 타워 표시는 바인딩 표시로 변환된다. 이 변환에 성공하면 인터페이스 ID, 오브젝트 UUID, 어노테이션 등의 다른 데이터는 조회 컨텍스트의 참조에서 검색된다. 엔드포인트 데이터베이스에 더 이상의 요소가 없을 때까지 이런 처리가 루프에서 이루어진다.
- rpc_mgmt_ep_unregister
서버가 엔드포인트에 더 이상 등록된 상태로 있지 않으려 할 때, 이 루틴이 호출된다. 그러면 서버의 위치 정보가 엔드포인트 데이터베이스에서 제거된다.
프로토타입 및 I/O 매개변수:
void rpc_mgmt_ep_unregister(IN rpc_binding_handle_t ep_binding, IN rpc_if_id_p_t if_id, IN rpc_binding_handle_t binding, IN uuid_p_t object_uuid, OUT unsigned32 *status);
지정된 인터페이스, 바인딩 핸들의 목록(지원되는 각 프로토콜에 대해 각각 하나씩) 및 지정된 오브젝트 UUID의 목록에서 등록 취소가 완료된다. 모든 입력 매개변수의 유효성 검증이 끝난 후, 엔드포인트 데이터베이스에 액세스하기 위한 참조를 가져온다. 입력 목록에 지정된 각 바인딩의 경우, 타워 표시에 대한 액세스가 이루어지는 타워에 대한 참조 목록을 가져온다. 또한, 입력 목록에 지정된 각 오브젝트 UUID에 대해 엔드포인트에서 이들을 삭제하기 위한 명령이 실행된다. 그런 다음, 타워를 사용할 수 있게 된 후 그 타워에 대한 참조를 사용할 수 있게 된다. 지정된 모든 바인딩이 입력 목록에서 사라질 때까지 이 프로세스가 계속 진행된다.
모든 관리 루틴은 서버의 수신 대기 상태에 대한 정보, 서버에 대한 통계, 등록된 인터페이스 목록 등을 얻기 위한 것이다. 호출은 바인딩 핸들을 바탕으로 로컬 또는 원격으로 실행된다. NULL 바인딩 핸들은 호출이 로컬에서 실행됨을 나타낸다.
- rpc_mgmt_is_server_listening
애플리케이션은 때때로 특정 서버가 수신 대기 중인지 여부를 확인하려 할 수 있다. 이 루틴에 대한 입력으로 바인딩 핸들을 전달하여 같은 정보를 파악할 수 있다. 실제 값은 서버가 수신되는 요청에 대해 수신 대기 중임을 나타낸다.
프로토타입 및 I/O 매개변수:
boolean32 rpc_mgmt_is_server_listening(IN rpc_binding_handle_t binding_handle, OUT unsigned32 *status);
이 카테고리에서 앞서 설명한 바와 같이, NULL 바인딩 핸들은 이 호출이 로컬 호스트 자체에서 실행됨을 나타낸다. 또는 바인딩 핸들이 원격으로 사용하기에 유효하고 호출이 그 원격 호스트에서 실행되는지 검사하기 위해 우선 바인딩 핸들의 유효성 검증을 한다. 수신 대기 중인 모든 서버는 등록된 포트에서 수신하는 소켓이 있는 경우 True로 설정되는 플래그를 유지 관리한다. 런타임에서 수신 소켓을 활성화할 수 없는 경우에는 False로 설정된다.
이 플래그의 값은 호출 애플리케이션에 대한 쿼리가 실행되는 순간에 리턴된다. 반대로, 애플리케이션은 rpc_mgmt_stop_server_listening을 호출하여 서버에 수신을 중지할 것을 요구할 수 있다. 그러면 보류 중이거나 진행 중인 요청이 완료되고 서버는 새 요청을 수락하지 않고 수신을 중지한다.
- rpc_mgmt_inq_stats
인터페이스가 올바로 작동 중인지 검사해야 할 때가 있을 수 있다. 그런 경우, 전송 또는 수신된 패킷 수와 해당 인터페이스에서 전송하거나 수신하는 RPC 호출 수와 같은 통계를 얻으면 디버깅에 도움이 된다.
프로토타입 및 I/O 매개변수:
void rpc_mgmt_inq_stats(IN rpc_binding_handle_t binding_handle, OUT rpc_stats_vector_p_t *statistics, OUT unsigned32 *status);
이 루틴은 앞서 언급한 통계를 검색하기 위해 호출된다. 프로토콜 서비스는 관리 시작점 벡터를 사용하여 쿼리되고, 해당 시스템에서 지원되는 각 프로토콜에 대해 통계가 검색된다.
여기에는 이름 서비스 항목, 그룹 및 프로파일 관리가 포함된다.
- rpc_ns_mgmt_entry_create
데이터베이스에 대한 적당한 액세스 권한이 있는 애플리케이션은 이름 서비스 데이터베이스에 저장될 이름을 만들 수 있다. 그러면 필요에 따라 다른 애플리케이션이 이 이름에 액세스할 수 있다.
프로토타입 및 I/O 매개변수:
void rpc_ns_mgmt_entry_create(IN unsigned32 entry_name_syntax, IN unsigned_char_p_t entry_name,OUT unsigned32 *status);
우선, 이름 서비스 항목 표시에 대한 참조는 주어진 항목 이름에서 얻어야 한다. 이 표시는 이름과 이름의 길이가 필드로 들어 있는 구조이다. 이 참조는 주어진 항목 이름을 확장하고 완전한 이름과 길이를 검색하여 얻는다. 여기에는 항목 이름을 구문 분석하여 이를 호환 가능 형식으로 변환하는 세부적인 프로세스가 필요하다. 이 참조는 이름 서비스 데이터베이스에서 항목을 작성하는 데 사용된다.
- rpc_ns_mgmt_entry_create
이 루틴은 이름 서비스 데이터베이스에서 서버 항목을 작성한다. 서버 항목에는 인터페이스 ID, 바인딩 정보 및 선택적으로 오브젝트 UUID가 들어 있다. 인터페이스 ID는 인터페이스 UUID와 그 버전 번호로 구성된다. 이것은 적당한 인터페이스를 찾았는지 클라이언트가 검색하는 데 사용되는 ID이다.
프로토타입 및 I/O 매개변수:
void rpc_ns_mgmt_entry_create(IN unsigned32 entry_name_syntax, IN unsigned_char_p_t entry_name, OUT unsigned32 *status);
entry_name_syntax는 항목 이름의 구문을 지정하는 정수 값이다. NULL이 전달될 때, 해당 항목에 대한 기본 구문이 사용된다. 이 루틴에서는 항목에 사용할 구문을 확인한 후 전달된 항목을 이름 서비스 표시로 변환한다. 마지막으로, 관련 항목이 이름 서비스 데이터베이스에서 작성되고 루틴이 호출자에게 리턴한다.
- rpc_ns_group_mbr_add
RPC 런타임은 이름 서비스 데이터베이스를 쿼리하거나 액세스하여 얻는 요소, 그룹, 프로파일 및 타워에 대한 조회 루틴을 제공한다.
이 루틴은 그룹 항목에 멤버를 추가하는 데 사용된다. 그룹 항목은 멤버와 같은 인터페이스를 제공하는 서버 항목을 가지게 될 이름 서비스 항목이다. 클라이언트는 한 그룹에서 같은 인터페이스를 제공하는 모든 멤버를 검색하여 적당한 서버를 찾는다.
프로토타입 및 I/O 매개변수:
oid rpc_ns_group_mbr_add(IN unsigned32 group_name_syntax, IN unsigned_char_p_t group_name, IN unsigned32 member_name_syntax, IN unsigned_char_p_t member_name,OUT unsigned32 *status);
이 루틴은 그룹과 멤버의 구문을 지정하는 정수 값인 group_name_syntax와 member_name_syntax를 입력으로 취한다. 이들의 값이 NULL인 경우 둘 모두에 대해 기본 구문이 사용된다. Group_name과 member_name은 각각 사람이 읽을 수 있는 형식으로 된 그룹 이름과 멤버 이름이다.
우선 이 루틴은 그룹 이름 구문을 내부 양식으로 변환한 다음, 그룹 이름이 이름 서비스 표시로 변환된다. 이와 유사하게, 멤버 이름 구문이 내부 양식으로 변환되고 멤버 이름은 이름 서비스 표시로 변환된다. 이 루틴은 이름 서비스 데이터베이스에서 그룹 이름을 검색하고, 아무 것도 찾지 못한 경우 그룹 항목이 작성된 후 새로 작성된 그룹에서 멤버 항목이 추가된다. 그룹 항목을 올바로 찾은 경우, 이 루틴은 지정된 그룹에 멤버 항목을 단순히 추가한다.
- rpc_ns_group_mbr_inq_begin
이 루틴은 그룹 멤버를 호출자에게 리턴할 목적으로 조회 컨텍스트를 시작한다. 조회 컨텍스트는 그룹 멤버, 프로파일, 타워 또는 UUID 멤버에 대해 수행되는 조회를 위해 내부적으로 유지되는 구조에 대한 포인터일 뿐이다.
프로토타입 및 I/O 매개변수:
void rpc_ns_group_mbr_inq_begin(IN unsigned32 group_name_syntax, IN unsigned_char_p_t group_name, IN unsigned32 member_name_syntax, OUT rpc_ns_handle_t *inquiry_context, OUT unsigned32 *status);
이 루틴은 우선 그룹 이름 구문을 내부 형식으로 변환한 후, 사람이 읽을 수 있는 그룹 이름을 이름 서비스 표시로 변환한다. 그 다음, 이 루틴은 멤버 이름 구문을 내부 양식으로 해결한다. 마지막으로, 이 루틴은 그룹 멤버에 대한 조회 컨텍스트를 작성하고 조회 컨텍스트 구조에서 멤버 이름 구문을 설정하고 작성된 조회 컨텍스트 구조에 대한 포인터를 호출자에게 리턴한다. 그러면 이 조회 컨텍스트 포인터/핸들이 그룹에서 멤버를 리턴하는 rpc_ns_group_mbr_inq_next 루틴으로 전달된다.
- rpc_ns_group_mbr_inq_next
이 루틴은 특정 그룹에 대한 멤버를 가져오기 위한 rpc_ns_group_mbr_inq_begin 이후에 사용된다.
프로토타입 및 I/O 매개변수:
void rpc_ns_group_mbr_inq_next(IN rpc_ns_handle_t inquiry_context, OUT unsigned_char_p_t *member_name, OUT unsigned32 *status);
이 루틴은 rpc_ns_group_mbr_inq_begin에서 리턴한 조회 컨텍스트 핸들을 입력으로 취한다. 이 루틴은 우선 전달된 조회 컨텍스트가 NULL이 아니고 그룹 멤버에 대한 컨텍스트인지 검사한다. 전달된 조회 컨텍스트가 NULL이거나 그룹 멤버 조회를 위한 것이 아닌 경우, 이 루틴은 rpc_s_invalid_ns_handle을 리턴한다. 그런 다음, 그룹의 멤버를 읽어 이름 서비스 형식에서 멤버 이름을 사람이 읽을 수 있는 형식으로 변환하여 호출자에게 리턴한다.
- rpc_ns_group_mbr_inq_done
이 루틴은 rpc_ns_group_mbr_inq_begin에 대한 이전 호출을 설정한 조회 컨텍스트를 종료하기 위해 호출된다.
프로토타입 및 I/O 매개변수:
void rpc_ns_group_mbr_inq_done (IN, OUT rpc_ns_handle_t *inquiry_context, OUT unsigned32 *status);
이 루틴은 우선 전달된 조회 컨텍스트가 NULL이 아니고 그룹 멤버 조회를 위한 것인지 검사한다. 전달된 조회 컨텍스트가 NULL이거나 그룹 멤버 조회를 위한 것이 아닌 경우, 이 루틴은 rpc_s_invalid_ns_handle을 리턴한다. 이 루틴은 단지 rpc_ns_group_mbr_inq_begin에서 조회 컨텍스트 구조에 할당된 메모리를 사용할 수 있게 한다.
본 기사에서는 RPC 클라이언트 및 서버 애플리케이션이 만드는 가장 기본적이고도 중요한 루틴들에 대해 설명했다. 또한, RPC 런타임이 어떻게 각 루틴의 기능을 실현하는지도 설명했다. 독자에게 RPC 런타임의 작동에 관한 정확하고 깊은 지식을 전달하려고 노력했다.
교육
-
Guide to Writing DCE applications
-
Power Programming with RPC
-
Communications Programming Concepts-- Programming in RPC
토론
- Twitter의 developerWorks 페이지를 살펴보자.
- My developerWorks 커뮤니티에 참여하자.
- AIX 및 UNIX 포럼에 참여하자.
- AIX Forum
- AIX Forum for developers
- Cluster Systems Management
- IBM Support Assistant Forum
- Performance Tools Forum
- Virtualization Forum
- 기타 AIX and UNIX Forums

Anupama works as Level 3 support member for IBM DCE and TXSeries products and has over 7 years of experience in the IT industry. She has written one other article for developerWorks, Know your TCP system call sequences. You can contact Anupama at anubindu@in.ibm.com.
Srinath Karanam works as a systems software engineer at the IBM India Software Labs and holds a bachelor's degree in electronics engineering. He has been part of the OS/2® LAN Server support team for the past three years and has played an active role in the development of WLAN supplicant's protocol stack on OS/2 for an IBM customer. You can contact him at srinathk@in.ibm.com.