Know-how: Kommunikation mit Remote Procedure Calls

RPC-Server

Nach diesen Vorbereitungen lässt sich der Server implementieren. Den RPC-Mechanismus kann der Programmierer auf verschiedene Protokolle aufsetzen. Das gewünschte Protokoll wird in Form einer Zeichenkette spezifiziert. Die Zeichenkette besteht aus einer Kennung für das RPC-Protokoll: ncacn oder ncadg für strom- oder paketorientierte Kommunikation. Anschließend folgen die Kennungen für ein Vermittlungsprotokoll, wie etwa IP, und ein Transportprotokoll, zum Beispiel TCP. Die einzelnen Bestandteile sind durch _-Zeichen getrennt.

Damit ist die Spezifikation für TCP/IP ncacn_ip_tcp. Ein anderes Beispiel ist ncacn_np für die Kommunikation über named pipes. Das Protokoll zusammen mit dem Namen des Endpunkts wird mit der Funktion RpcServerUseProtseqEp angegeben. Anschließend wird mit RpcServerRegisterIf das Interface registriert. Schließlich wartet mit RpcServerListen der Server auf Anfragen. Insgesamt erhält man folgenden Code für den Server:

/* file: telbus.c */
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include "telbu.h"

void main()
{
RPC_STATUS status;
unsigned char *pszProtocolSequence = "ncacn_ip_tcp";
unsigned char *pszSecurity = NULL; /*no Security*/
unsigned char *pszEndpoint = "5432";
unsigned int cMinCalls = 1;
unsigned int cMaxCalls = 20;
unsigned int fDontWait = FALSE;

printf( "RpcServerUseProtseqEp\\n");
status = RpcServerUseProtseqEp(pszProtocolSequence, cMaxCalls, pszEndpoint, pszSecurity);

if (status) exit(status);
printf( "RpcServerRegisterIf\\n");
status = RpcServerRegisterIf(telbu_v1_0_s_ifspec, NULL, NULL);
if (status) exit(status);

printf( "RpcServerListen\\n");
status = RpcServerListen(cMinCalls, cMaxCalls, fDontWait);

if (status) exit(status);

} // end main()

/******************************************************/
/* MIDL allocate and free */
/******************************************************/

void __RPC_FAR * __RPC_USER midl_user_allocate(size_t len)
{
return(malloc(len));
}

void __RPC_USER midl_user_free(void __RPC_FAR * ptr)
{
free(ptr);
}

Zusätzlich werden zwei Routinen zum Reservieren und Freigeben von Speicher benötigt. Die beiden Routinen sind hier lediglich Hüllen (wrapper) um die entsprechenden Funktionen malloc und free aus der Standardbibliothek von C.