15. RPC - Remote Procedure Call

Transcrição

15. RPC - Remote Procedure Call
15.
RPC - Remote Procedure Call
• Historisch gesehen eine Vorstufe für RMI (Vorsicht bei Stub-Namen!).
• Für die Implementierung von Klienten-Server Szenarien.
• Berücksichtigt heterogene
Umgebungen bezüglich:
Klient
Server
- Betriebssystemplattformen,
- Byteanordnungen,
- Containergrößen.
• Nachbildung eines lokalen
Prozeduraufrufes:
- Über Rechnergrenzen und
Adressräume hinweg,
- Synchrone Aufrufssemantik,
- Übergabe von Parametern,
- Rückgabe des Resultats,
- Aber kein Kontext.
Verteilte Betriebssysteme, 2003/2004, VS, Universität Ulm
Client-Stub
marshall
unmarshall
Server-Stub
marshall
unmarshall
1
15.1 RPC-Programmherstellung:
• *.c, *.acf, *.idl-Dateien,
• MIDL,
Server.c
Client.c
Interf.acf
Interf.idl
• Stubs,
MIDL Compiler
• C,
• Linker,
Interf_C.C (stub)
Interf.h
Interf_S.C (stub)
• Run time …
C Compiler
Client.obj.
Server.obj
C Compiler
Interf_C.obj
Interf_S.obj
Client run time
Linker
Client.exe
Verteilte Betriebssysteme, 2003/2004, VS, Universität Ulm
Linker
Server run time
Server.exe
2
15.2 Attribute Configuration File interf.acf :
[ implicit_handle(handle_t string_IfHandle) ] interface Interf { }
• Mit implicit_handle benutzt das RPC Laufzeitsystem immer die
spezifizierte globale Variable:
RPC Library
Implicit handle
• explicit_handle erlaubt verschiedene Remote-Interfaces per RPC
anzusprechen, eventuell unter Verwendung unterschiedlicher Stubs:
void ExplicitRemoteProcX( handle_t whichServer, [string] char * printMsg);
• auto_handle erledigt die Bindung automatisch und wählt zwischen
explizit und impliziter RPC Handle, je nachdem, ob beim
Prozeduraufruf ein Prozedurparameter erscheint
Verteilte Betriebssysteme, 2003/2004, VS, Universität Ulm
3
15.3 Interface Definition File interf.idl :
• Spezifiziert die Schnittstelle der Remote-Prozedur auf dem Server,
• Universally Unique Identifier mit Programm uuidgen erzeugen,
• Schnittstelle hat nur Routinen, ist also kein Objekt,
• IDL als erweiterte Datendeklaration in C,
• Kein strenges Typenkonzept.
[ uuid(5AFEB070-D4D5-11d0-9451-002018304F6C), version (1.0), ]
interface Interf {
void Print( [in, string] unsigned char *pszString);
}
Klient
Verteilte Betriebssysteme, 2003/2004, VS, Universität Ulm
IDL
Server
4
15.4 Parameterübergabe und IDL-Attribute
• Marshalling: Konvertierung zwischen Hostformat & Netzwerkformat.
• Verschiedene Datentypen als maschinenunabhängiges Format:
-
boolean, byte, char, double, float, hyper, long, short, small, wchar_t …
Stringformat berücksichtigen,
Containergrössen,
Byte-Order:
Verteilte Betriebssysteme, 2003/2004, VS, Universität Ulm
5
• Übergabe von Zeigern in den fremden Adressraum:
-
Übergabe dynamischer Strukturen nur mit sogenannter "Pointer Emulation",
Parameter-Übergabe nötigenfalls nach dem Prinzip von Copy-Restore,
Referenz-Zeiger sind konstant und enthalten nie den Wert NULL,
Unique-Zeiger dürfen im Zeitpunkt des Aufrufs Null sein, lassen aber eine
Allozierung des zurückgelieferten Parameterobjektes zu,
- Full-Pointer zeigen auf ein Objekt, auf welches es auch Alias-Zeiger geben darf,
- Kein automatische Hüllenbildung.
• Übergabemodell für Werte und Zeiger:
-
"Hallo Server !"
Als Kopie des Wertes,
Als Adresse des Wertes,
Als Adresse der Zeigervariablen,
Als Menge aller Zeiger auf das Objekt.
Verteilte Betriebssysteme, 2003/2004, VS, Universität Ulm
6
• Parametertransport mit speziellen Attributen:
[in]
- [string, …] mit Nullcharacter abgeschlossener String,
- [out, …] nur auf dem Rückweg übertragen,
[out]
- [in, ...] nur auf dem Hinweg übertragen.
Server
• Weitere Attributfunktionen:
- size_is(..), max_is, min_is, first_is, last_is, length_is …
- zum Beispiel für einen Array variabler Größe:
// weiteres IDL-Dateibeispiel
size_is
// Name des Attributes, muss separat deklariert werden
interface RPC_Array // vgl. Hamilton & Williams "Windows NT4.0..." SAMS Verlag
{
extern short Size;
// im Klientenprogramm angesiedelt
void myArrayProc( [in, size_is(Size)] char Array[*] )
// Array variabler Größe
…}
• Attribute für RPC Binding-Handles:
- [auto_handle] interface myServices,
- [implicit_handle(handle_t InterfHdl] interface fixedService ),
- [explicit_handle] verlangt beim RPC einen zusätzlichen Handle-Parameter.
Verteilte Betriebssysteme, 2003/2004, VS, Universität Ulm
7
15.5 Quellprogramm client.c:
• Argument auf der Befehlszeile enthält einen auszugebenden String.
• Durch MIDL erzeugte Interface-Headerdatei mitcompilieren.
• u.a. der Interface Handle ist in der Headerdatei versteckt.
• Bind( )-Funktion für Windows-RPC:
-
Zeichenkette zusammenstellen mit den nötigen Binde-Parametern,
Je nach gewähltem Protokoll Verbindung implizit aufbauen,
Viele Protokollvarianten wählbar über eine Kennung;
Z.B. "ncagn_np" für Microsoft Named Pipes
#include <stdlib.h>
#include <stdio.h>
#include <windows.h>
#include "..\interf.h"
// File Client.c
void main(int argc, char **argv){
RPC_STATUS status;
unsigned char *pszStringBinding=NULL;
unsigned char *pszString = &argv[1];
// Cmndline Argument implied !
// status of RPC
// binding handle as string
// string to print
Verteilte Betriebssysteme, 2003/2004, VS, Universität Ulm
8
// make a concatenated string to feed the binding function - ignore errors here
status = RpcStringBindingCompose(NULL, "ncacn_np", // proto.seq.=named-pipe
NULL,
// network-address (half open)
"\\pipe\\hello", NULL, // end-point (pipe name)
&pszStringBinding ); // the combined string
status = RpcBindingFromStringBinding( pszStringBinding, &string_IfHandle);
// now do the RPC
RpcTryExcept { Print(pszString); }
// try our remote print function, use RPC-Macro
RpcExcept(1)
// every exception is handled here
{ printf("Runtime reported exception 0x%lx\n", RpcExceptionCode() ); }
RpcEndExcept
// end the try block, use RPC-Macro
//might need to free the strings allocated by the RPC run-time library
status = RpcStringFree(&pszStringBinding);
// should check for error
status = RpcBindingFree(&string_IfHandle);
// should check for error
exit(0);
}
// allocate and free memory for an RPC client object (here string)
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); }
Verteilte Betriebssysteme, 2003/2004, VS, Universität Ulm
9
15.6 Quellprogramm server.c:
• Protokollsequenz auswählen.
• Server-Interface registrieren. Handle wird durch Midl deklariert.
• Server einschalten zur Entgegennahme von RPCs - concurrently.
• Server stoppen, keine weiteren RPCs.
• Registrierung wieder entfernen.
• Allozierungsroutinen für die Laufzeitumgebung bereitstellen:
- Objekte beim Aufruf allozieren,
- Beim Rücksprung freigeben.
#include <stdlib.h>
#include <stdio.h>
#include <windows.h>
#include "..\string.h"
// >>>>>>>>
Datei Server.c (Teil 1) <<<<<<<<<<<<<
// name of the remote interface
void Print(unsigned char *pszString) { printf("RPC: %s\n", pszString); }
Verteilte Betriebssysteme, 2003/2004, VS, Universität Ulm
// rpc exported func
10
void main(int argc, char **argv) {
RPC_STATUS
status;
// >>>>>
Datei Server.c (Teil 2) <<<<
// result status of RPC
// tells the RPC library to use the specified protocol sequence combined
// with the specified endpoint for receiving remote procedure calls.
status = RpcServerUseProtseqEp("ncacn_np", 20,
// named-pipe, # of concurrent calls
"\\pipe\\hello", NULL ); // end-point name, security descr.
// register interface with the RPC library
status = RpcServerRegisterIf(string_ServerIfHandle, // interface to register (created by midl)
NULL, NULL );
// nil UUID, default entry-point-vector
// start the RPC server, ignore errors !
status = RpcServerListen( 1, 20, 1);
// concurrent calls in [1..20], don't wait
getchar();
status = RpcMgmtStopServerListening(NULL);
// wait for any key to shutdown server
// shutdown and stop listening
status = RpcServerUnregisterIf( NULL,NULL,FALSE );
// unregister any interface
// interface to unregister, unregister interface for all UUIDs, shutdown without wait
// allocates and frees memory for an RPC client object (here string)
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 ); }
Verteilte Betriebssysteme, 2003/2004, VS, Universität Ulm
11

Documentos relacionados