III RPC Zdalne wywoływanie procedur (ang. Remote Procedure Calls ) 1. Koncepcja Aplikacja wywołanie procedury parametry wyniki wykonanie procedury wynik komputer klienta komputer serwera Zaletą takiego rozwiązania jest : a) przeźroczystość rozproszenia (ukrycie faktu komunikacji) b) podniesienie przeźroczystości dostępu (niezależność od sposobu reprezentacji danych w systemu operacyjnym)
2. Realizacja procedura procedury serwera stopka klienta parametry wyniki stopka serwera sieć funkcje sieciowe kontekst jądra funkcje sieciowe kontekst jądra proces klienta proces serwera proces klienta wywołuje procedurę stopka procedury koduje nazwę procedury i jej parametry do uniwersalnego formatu (XDR), tworzy komunikat sieciowy i wysyła go do serwera za pomocą funkcji systemowych proces serwera odbiera komunikat za pomocą funkcji systemowych i przekazuje go do stopki serwera stopka serwera rozkodowuje komunikat a następnie wywołuje odpowiednią procedurę serwera przekazując jej parametry procedura jest wykonywana przez proces serwera, która przy zakończeniu zwraca wartość do stopki serwera stopka serwera koduje do formatu XDR otrzymaną wartość, a następnie tworzy komunikat, który jest wysyłany do procesu klienta stopka klienta odbiera komunikat, dekoduje go i otrzymany wynik przekazuje w procesie klienta jako wynik wykonania procedury
3. Komunikacja między klientem i serwerem rpcbind (portmap) rejestracja serwera lokalizacja program 1 proces klienta komunikacja RPC program 2 serwer komputer klienta komputer serwera zdalne procedury RPC są zgrupowane w programy i wersje, gdzie adresowanie odbywa się za pomocą IP komputera, numeru programu, numeru wersji, numeru procedury kiedy serwer startuje rejestruje swoje programy u serwera portmap kiedy klient chce wywołać zdalną procedurę przez RPC kontaktuje się z serwerem portmap ( port 111 ), który przekazuje mu numer portu dla odpowiedniej procedury (procedury należące do tej samej wersji mają przydzielony ten sam numer portu) Komunikacja między klientem i serwerem odbywa się za pomocą protokołów TCP lub UDP
4. Interfejs RPCGEN RPCGEN jest językiem i prekompilatorem, który pozwala tworzyć pliki w języku C: stopka klienta stopka serwera plik do konwersji danych w standardzie xdr plik nagłówkowy Typy danych akceptowane przez RPCGEN void pusty char znakowy short int, int long int, usigned całkowity float, double zmiennoprzecinkowy typ nazwa[zakres] tablica o stałej długości typ nazwa<zakres> tablica o zmiennej długości string łańcuch znaków struktura typ złożony typedef nazwa_typu definicja_typu uwaga: w przypadku korzystania z typów złożonych ( podwójne wskaxniki) należy użyć wcześniej deklaracji typedef 5. Tworzenie aplikacji przykład: definiuje interfejs zdalny /* ser.x */ struct arg { double x,y; }; program FUNKCJE { version VER1 { double suma( arg )=1; double iloczyn (arg )=2; // numer procedury } =1; // numer wersji } 0x20000001; // numer programu uwaga: funkcje mogą przekazywać tylko jeden argument
generowanie stopki klienta i stopki serwera $ rpcgen ser.x wynik: ser.h ser_svc.c ser_clnt.c ser_xdr.c plik nagłówkowy plik stopki serwera plik stopki klienta plik konwersji danych tworzenie serwera a) edycja pliku serwer.c #include <rpc/rpc.h> #include ser.h double* suma_1_svc ( arg *a, struct svc_req * r) { static double wynik; wynik=a->x+a->y; return &wynik; } double* iloczyn_2_svc ( arg *a, struct svc_req * r) { static double wynik; wynik=a->x*a->y; return &wynik; } b) kompilacja: $ gcc serwer.c ser_svc.c ser_xdr.c -o serwer
tworzenie programu klienta a) edycja pliku klient.c #include <rpc/rpc.h> #include ser.h int main() { char host[100]; CLIENT *kl; double *wynik; arg a; printf("nazwa serwera: "); scanf("%s",host); kl=clnt_create(host,funkcje,ver1,"tcp"); if (kl==null ) {perror("blad servera"); exit(0);} printf("podaj dwie liczby: "); scanf("%d%d",&a.a,&a.b); wynik=suma_1(&a,kl); if (wynik!=null) printf("suma=%d\n",*wynik); wynik=iloczyn_1(&a,kl); if (wynik!=null) printf("iloczyn=%d\n",*wynik); return 0; } b) kompilacja: $ gcc klient.c ser_clnt.c ser_xdr.c -o klient
5. Korzystanie z pliku makefile $ rpcgen -a ser,x wynik: Makefile.ser ser.h ser_svc.c ser_clnt.c ser_xdr.c plik makefile plik nagłówkowy plik stopki serwera plik stopki klienta plik konwersji danych ser_server.c plik programu serwera ( do edycji ) ser_client.c plik programu klienta ( do edycji ) Pliki ser_server.c, ser_client.c edytuje się dla własnej aplikacji kompilacja programu: $ make -f Makefile.ser wynik: ser_server ser_client wykonywalny plik serwera wykonywalny plik clienta
Ćwiczenia Pliki: RPC/ MAKEFILE/ start.x ECHO/ ser.x klient.c serwer.c CALC/ ser.x NIEBLOKUJACE/ Makefile.ser ser.x klient.c serwer.c NIEBLOKUJACE2/ Makefile.ser ser.x klient.c serwer.c BAZA/ Makefile.ser ser.x czytelnik.c pisarz.c serwer.c Ćwiczenia: 1) program echo : wejść do katalogu ECHO $ rpcgen ser.x skompilować serwer: $ gcc serwer.c ser_svc.c -o serwer skompilować klient: $ gcc klient.c ser_clnt.c -o klient uruchomić serwera i klienta w oddzielnych konsolach 2) program obliczający sumę i iloczyn dwóch liczb wejść do katalogu CALC $ rpcgen -Ss ser.x -o serwer.c zdefiniować program serwera ( edycja pliku: serwer.c ) zdefiniować program klienta (plik: klient.c ) skompilować serwer: $ gcc serwer.c ser_svc.c ser_xdr.c -o serwer skompilować klient: $ gcc klient.c ser_svc.c ser_xdr.c -o klient sprawdzić działanie aplikacji 3) korzystanie z pliku makefile usunąć pliki: $ make clean -f Makefile.ser skompilować pliki: $ make -f Makefile.ser sprawdzić działanie aplikacji Zadania: 1) Aplikacja w której działają dwa procesy oraz serwer RPC. Jeden proces wykonuje zapis (struktura) do bazy umieszczonej na serwerze RPC. Drugi proces wykonuje odczyt lub sprawdzenie czy szukany obiekt (struktura) znajduje się w bazie. 2) Rozproszona baza danych. Aplikacja w której działają dwa procesy oraz kilka serwerów RPC. Jeden proces wykonuje zapis do bazy umieszczonej na którymkolwiek serwerze serwerze RPC. Operacja zapisu do bazy musi być powielona na pozostałych serwerach RPC. Drugi proces wykonuje odczyt lub sprawdzenie czy szukany obiekt jest w bazie na dowolnym serwerze RPC. Uwaga: bazą danych jest tablica struktur 3) Rozproszona baza danych dostęp większościowy. Aplikacja taka jak w punkcie (2) z tą różnicą że operacja zapisu jest powielona tylko na 50% +1 serwerów RPC a odczyt jest dokonywany z 50% serwerów i wybierana jest wartość z największą datą. Uwaga: zapis do bazy powinien być zliczany liczbą typu long, która jednocześnie oznacza datę zapisu.
4) Synchronizacja zegarów: Jest ustalona liczba procesów np. 3. Procesy działające w różnych systemach operacyjnych mają synchronizować własne zegary. Każdy proces ma swój lokalny serwer RPC na tym samym komputerze. Proces wykonuje pętlę nieskończoną w której sumuje wartości 1.0. Co jakiś czas proces chce synchronizować wartość sumy z wartościami które obliczają pozostałe procesy. W tym celu wywołuje procedurę RPC pobierz_czas na swoim komputerze, a następnie porównuje pobraną wartość z aktualnie wyliczoną sumą. Jeżeli wartość ta jest większa to aktualizuje sumę tą wartością +1. Następnie wykonuje procedurę RPC zapisz_czas na losowo wybranym zdalnym serwerze. Komunikacja jest przedstawiona na schemacie. P1 P2 P3 RPC-1 RPC-2 RPC-3 5) Komunikator. Korzystając z systemu RPC napisać komunikator dla dwóch klientów którzy interakcyjnie mogą wymieniać informacje w postaci tekstu na dwóch zdalnych komputerach.