Systemy rozproszone W. Bartkiewicz

Slides:



Advertisements
Podobne prezentacje
Tablice 1. Deklaracja tablicy
Advertisements

C++ wykład 2 ( ) Klasy i obiekty.
C++ wykład 4 ( ) Przeciążanie operatorów.
Język C/C++ Funkcje.
Programowanie obiektowe
Zdalne wywołania procedur
Mechanizmy pracy równoległej
Deklaracje i definicje klas w C++ Składowe, pola, metody Konstruktory
Programowanie obiektowe
Wzorce.
Język ANSI C Funkcje Wykład: Programowanie komputerów
Prowadzący: mgr inż. Elżbieta Majka
Systemy rozproszone W. Bartkiewicz
Systemy rozproszone W. Bartkiewicz
PROGRAMOWANIE STRUKTURALNE
CORBA Łukasz Wnęk.
Rozszerzalność systemów rozproszonych
Autor Roman Jędras Prowadzący: dr inż. Antoni Izworski Przedmiot:
Materiały do zajęć z przedmiotu: Narzędzia i języki programowania Programowanie w języku PASCAL Część 7: Procedury i funkcje © Jan Kaczmarek.
Systemy rozproszone Komunikacja (I)
Struktury.
Tablice.
Systemy operacyjne Wykład nr 5: Wątki Piotr Bilski.
Systemy operacyjne Wykład nr 4: Procesy Piotr Bilski.
Usługi sieciowe Wykład 5 DHCP- debian Jarosław Kurek WZIM SGGW 1.
Biblioteki i przestrzenie nazw
C++ wykład 2 ( ) Klasy i obiekty.
Systemy operacyjne.
Gniazda komunikacji sieciowej w języku Java
Typy prywatne 1 Typy prywatne W Adzie typy prywatne (private types) służą do bezpiecznego udostępniania danych zdefiniowanych w pakiecie, z którego korzysta.
Wykład 1: Wskaźniki Podstawy programowania Programowanie w C
Język ANSI C Operacje we/wy
Komunikaty sterujące zestawu protokołów TCP/IP
Artur Szmigiel Paweł Zarębski Kl. III i
12. GNIAZDA BSD Biblioteka funkcji związanych z gniazdami jest interfejsem programisty do obsługi protokołów komunikacyjnych. Została utworzona dla Unixa.
Semafory według normy POSIX
9. KOORDYNACJA PROCESÓW WSPÓŁBIEŻNYCH PRZY UŻYCIU INTERPRETATORA
Wątki.
nowe operatory & . (kropka) * operator rzutowy -> , (przecinek)
Podstawy programowania
Podstawy programowania II
Podstawy programowania II Wykład 2: Biblioteka stdio.h Zachodniopomorska Szkoła Biznesu.
Podstawy programowania
Protokół Komunikacyjny
Systemy operacyjne.
Budowa systemu komputerowego
Automatyka i Robotyka Systemy czasu rzeczywistego Wykład 4.
Prezentacja i szkolenie
Sieci komputerowe.
Programowanie obiektowe – zastosowanie języka Java SE
Wykład IV Protokoły BOOTP oraz DHCP.
Przekazywanie parametrów do funkcji oraz zmienne globalne i lokalne
Programowanie obiektowe 2013/2014
Aplikacje TCP i UDP. Łukasz Zieliński
Kurs języka C++ – wykład 9 ( )
Systemy operacyjne (wiosna 2014)
Systemy rozproszone  Rozdzielenie obliczeń między wiele fizycznych procesorów.  Systemy luźno powiązane – każdy procesor ma lokalną pamięć; procesory.
Programowanie strukturalne i obiektowe C++
Kurs języka C++ – wykład 4 ( )
Model OSI.
Piotr Czapiewski Wydział Informatyki ZUT. Web Services Description Language.
© DSRG 2004 Systemy Rozproszone - Zdalne wywołanie procedury 1 Zdalne wywołanie procedury Implementacja Sun RPC Ćwiczenie laboratoryje:
Obiekty COM Przemysław Buczkowski. Plan prezentacji 1.Wprowadzenie do COM 2.Historia standardu 3.Jak działa COM 4.Interface IUknown 5.Paradygmaty COM.
Model warstwowy ISO-OSI
Seminarium Dyplomowe: Metodyka i Techniki Programowania Autor: Bartłomiej Fornal.
K URS JĘZYKA C++ – WYKŁAD 3 ( ) Przenoszenie Składowe statyczne Funkcje wbudowane Argumenty domyślne.
Programowanie obiektowe – zastosowanie języka Java SE
Aplikacje i usługi internetowe
nowe operatory & . (kropka) * operator rzutowy -> , (przecinek)
Zapis prezentacji:

Systemy rozproszone W. Bartkiewicz Uniwersytet Łódzki Katedra Informatyki W. Bartkiewicz Systemy rozproszone Wykład 5. Komunikacja międzyprocesowa z wykorzystaniem usług warstwy pośredniej - RPC

Oprogramowanie warstwy pośredniej Katedra Informatyki Oprogramowanie warstwy pośredniej to aplikacja, która logicznie przynależy do warstwy zastosowań, lecz zawiera wiele protokołów ogólnego przeznaczenia, niezależnych od innych, bardziej konkretnych aplikacji. Protokoły komunikacyjne oprogramowania warstwy pośredniej tworzą podstawy usług komunikacyjnych wysokiego poziomu. Do podstawowych usług komunikacyjnych oprogramowania warstwy pośredniej należą: Zdalne wywołania procedur (RPC). Zdalne wywołania obiektów. Obsługa kolejek komunikatów. Zaplecze strumieni komunikacji nośników ciągłych.

Zmodyfikowany model komunikacji sieciowej Katedra Informatyki Zastosowanie Warstwa pośrednia Transport Sieć Łącze danych Poziom fizyczny Protokół aplikacji Protokół warstwy pośredniej Protokół transportu Protokół sieci Protokół łącza danych Protokół fizyczny 6 5 4 3 2 1

RPC – Wywołania procedur zdalnych Katedra Informatyki RPC – Wywołania procedur zdalnych RPC jest konstrukcją ukrywającą działania komunikacyjne pod znaną abstrakcją wywołania procedury. Odwołanie do serwera ma po stronie klienta postać identyczną jak zwykłe wywołanie podprogramu. Abstrakcja ta ukrywa w rzeczywistości wysłanie odpowiedniego komunikatu do procesu serwera (określającego procedurę jaka ma zostać wykonana przez serwer), wykonanie przez serwer odpowiadającego mu przetwarzania i odesłanie odpowiedzi. Dane przesyłane przez klienta i niezbędne do wykonania przez serwer procedury, podawane są jako wartości parametrów. Odpowiedź serwera przekształcana jest na wartości parametrów wyjściowych oraz wartości powrotne z funkcji.

Katedra Informatyki Semantyka wywołań RPC Definicja zdalnej procedury określa parametry wejściowe i wyjściowe. Parametry wejściowe przekazywane są serwerowi jako wartości argumentów w komunikacie zamawiającym i kopiowane do zmiennych, które są przekazywane jako parametry do procedury w środowisku wykonawczym serwera. Parametry wyjściowe zwracane są klientowi w komunikacie z odpowiedzią, gdzie używa się ich do zastąpienia wartości odpowiednich zmiennych w środowisku wywołania. Jeśli parametr używany jest jako wejściowy i wyjściowy, to jego wartość musi zostać przesłana zarówno w zamówieniu jak i w odpowiedzi. Dostarczenie informacji o tym czy parametr używany jest na wejściu, wyjściu, czy w obu przypadkach powoduje konieczność zastosowania w każdym systemie RPC języka opisu interfejsu (IDL - Interface Definition Language).

Namiastki klienta i serwera Katedra Informatyki Namiastki klienta i serwera Jeśli dana procedura ma być wykonana zdalnie, to system RPC w programie klienta umieszcza jej inną wersję, tzw. namiastkę procedury (stub procedure) nazywaną namiastką klienta (client stub). Jest to normalny, lokalny podprogram o sygnaturze zgodnej z procedurą zdalną. Zgodność sygnatury osiągana jest poprzez wspólną definicję interfejsu. Namiastka klienta umieszcza identyfikator procedury oraz parametry w komunikacie, który wysyła do serwera wykorzystując lokalny SO. Następnie blokuje się w oczekiwaniu na odpowiedź serwera. W programie serwera system RPC instaluje tzw. ekspedytora (dispatcher) oraz namiastki procedur serwera (server stubs). Ekspedytor na podstawie identyfikatora procedury w komunikacie z zamówieniem wybiera odpowiednią namiastkę procedury, przekazując jej argumenty.

Namiastki klienta i serwera (c.d.) Katedra Informatyki Namiastki klienta i serwera (c.d.) Namiastka serwera rozpakowuje parametry z komunikatu, tworząc w środowisku serwera odpowiednie bufory zarówno dla danych wejściowych jak i wyników działania. Następnie wywołuje (również poprzez zwykłe wywołanie lokalne) procedurę zdalną serwera. Wykonuje ona swoje zadanie, zwracając również w normalny sposób wynik namiastce serwera. Namiastka serwera umieszcza wynik działania procedury w komunikacie z odpowiedzią dla klienta, wysyła go a następnie przechodzi w stan oczekiwania na nadejście następnego komunikatu. Namiastka klienta odbiera komunikat, rozpakowuje z niego wyniki, kopiuje je do obszarów pamięci w których oczekuje ich podprogram klienta wywołujący procedurę zdalną i kończy działanie w zwykły sposób.

Działanie RPC Komputer klienta Komputer serwera Proces klienta Katedra Informatyki Działanie RPC Komputer klienta Komputer serwera Proces klienta Odwrotne przetaczanie parametrów Przetaczanie wyników Przetaczanie parametrów Odwrotne przetaczanie wyników Przyjęcie zamówienia Wysłanie odpowiedzi Wykona-nie procedury Powrót Wywoła- nie lokalne Lokalny powrót Wysyłanie zamówienia Przyjęcie odpowiedzi Wybór procedury Moduł komunikacyjny (SO) Moduł komunikacyjny (SO) Namiastka procedury serwera Namiastka procedury klienta Procedura usługowa Klient Ekspedytor

Katedra Informatyki Specyfika wywołań RPC Procedura zdalna wykonywana jest w środowisku odmiennym od miejsca jej wywołania, toteż nie ma dostępu do zmiennych środowiska wywołania, np. do zmiennych globalnych zadeklarowanych w programie wywołującym. Proces przekazywania danych między różnymi środowiskami wykonawczymi nazywamy przetaczaniem (marshaling). W wieloplatformowych środowiskach RPC występuje konieczność uwzględnienia różnych reprezentacji binarnych danych, tzn. zdefiniowania protokołów ich przesyłania wspólnych dla serwera i klienta. Przekazywanie przez proces w komunikacie do innych procesów adresów komórek pamięci lub ich równoważników (np. odniesień, referencji, uchwytów) jest bezcelowe. Tak więc generalnie argumenty i wyniki procedur zdalnych nie powinny zawierać struktur danych ze wskaźnikami do komórek pamięci. Systemy RPC radzą sobie zwykle z przetaczaniem wskaźników (odniesień) do prostych tablic i struktur, kopiując (przesyłając) między namiastkami klienta i serwera całe wskazywane dane.

Język Opisu Interfejsu (IDL) Katedra Informatyki Język Opisu Interfejsu (IDL) Aby uprościć korzystanie z mechanizmów RPC, interfejsy definiujące zbiory podprogramów realizowanych przez serwer i możliwych do wywołania przez klienta, określane są zazwyczaj w specjalnym języku opisu interfejsu (IDL – Interface Definition Language). Zastosowanie wspólnej definicji interfejsu zarówno dla serwera, jak i klienta zapewnia, że typy argumentów i wartości powrotnych oraz protokoły przetaczania ich wartości, używane przez klienta będą zgodne ze zdefiniowanymi na serwerze. Definicje interfejsów zapisane w IDL kompilowane są przy użyciu kompilatora interfejsu, tworzącego składowe konsolidowane z programami serwera i klienta.

Zadania kompilatora interfejsu Katedra Informatyki Zadania kompilatora interfejsu Generowanie namiastek procedur klienta, odpowiadających sygnaturom procedur w interfejsie. Namiastki te zostaną skompilowane i połączone z programem klienta. Generowanie namiastek procedur serwera odpowiadających sygnaturom procedur w interfejsie. Namiastki te zostaną skompilowane i połączone z programem serwera. Na podstawie sygnatur procedur z interfejsu, określających typy argumentów i wartości powrotnych, wygenerowanie operacji przetaczania oraz odwrotnego przetaczania w każdej namiastce procedury. Wygenerowanie dla każdej procedury z interfejsu szablonu bibliotecznego charakterystycznego dla danego języka programowania (na przykład w języku C/C++ pliku nagłówkowego z deklaracjami sygnatur poszczególnych procedur). Programista dostarcza następnie ich implementacji.

Katedra Informatyki Wiązanie Definicja interfejsu określa tekstową nazwę usługi za pomocą której odwołują się do niej klienty. Dla celów komunikacyjnych niezbędne jest jednak dostarczenie klientom informacji o punkcie końcowym serwera. Przez wiązanie (binding) rozumiemy odwzorowanie nazwy usługi na konkretny identyfikator komunikacyjny, określający punkt końcowy serwera (identyfikator portu, grupy portów lub dowolna inna forma miejsca przeznaczenia) do którego wysyłane będą komunikaty. Program klienta zawierać może sieciowy adres serwera. Oznacza to jednak, że przy każdym przemieszczeniu serwera niezbędne jest poinformowanie o tym wszystkich klientów. Łącznik (binder) jest odrębną usługą utrzymującą tablicę odwzorowań nazw usług na punkty końcowe serwerów. Łącznik jest przykładem usług nazewniczych, w których rejestruje się serwery aby umożliwić ich lokalizację przez klientów.

Katedra Informatyki Uszkodzenia dostaw Komunikaty od czasu do czasu są gubione przez nadawców, odbiorców oraz bramy sieci. Sieci mogą ulegać podziałowi. Oznacza to, że jeden lub więcej węzłów sieci może zostać oddzielony od reszty sieci. Procesy ulegają niekiedy awariom. Ogólnie biorąc nadawca nie jest w stanie odróżnić awarii procesu od awarii komunikacyjnej. Jeśli proces nie odpowiada pomimo wykonania ustalonej liczby N prób skomunikowania się z nim, to zakłada się, że jest nieosiągalny. Wybór N jest trudny: jeśli będzie za małe, to można omyłkowo uznać proces za uszkodzony, natomiast gdy N będzie za duże to czas potrzebny na wykrycie uszkodzenia może stać się zbyt długi. Nie ma uszkodzeń danych. Komunikaty są odbierane poprawnie – zapewniają to mechanizmy wykrywania błędów na poziomie sieci.

Katedra Informatyki Protokoły wymiany RPC Protokół zamówienia (request – R). Może być używany w sytuacji, gdy procedura zdalna nie musi zwracać żadnej wartości, a klient nie wymaga potwierdzenia, że ją wykonano. Klient może kontynuować działanie natychmiast po wysłaniu komunikatu z zamówieniem, gdyż nie musi czekać na komunikat z odpowiedzią. Protokół zamówienie – odpowiedź (request-reply – RR). Polega na wymianie pary komunikatów zamówienie – odpowiedź. Nie są wymagane komunikaty potwierdzające, gdyż za potwierdzenie zamówienia klienta służy odpowiedź serwera. Protokół zamówienie – odpowiedź – potwierdzenie (request-reply-acknowledge reply – RRA).Zakłada wymianę trzech komunikatów, z dodatkowym potwierdzeniem od klienta do serwera. Komunikat potwierdzający odpowiedź zawiera identyfikator zamówienia, wzięty z odpowiedzi. Jego nadejście powoduje potraktowanie przez serwer wszystkich odpowiedzi o mniejszych identyfikatorach zamówień jako potwierdzonych. Tak więc zgubienie jakiegoś potwierdzenia jest nieszkodliwe.

Problemy gwarancji dostaw Katedra Informatyki Problemy gwarancji dostaw Na wypadek awarii serwera, lub zagubień komunikatów z zamówieniami lub odpowiedziami, namiastka klienta powinna stosować odliczanie czasu przy czekaniu na odpowiedź od serwera. Po wyczerpaniu czasu oczekiwania namiastka klienta może przerwać swoje działanie i wrócić do klienta, przekazując informację, że operacja się nie powiodła. Zazwyczaj jednak powtarza ona (retransmituje) wysyłanie komunikatu zamawiającego do czasu aż skończy się to powodzeniem lub stanie się prawie pewne, że opóźnienie wynika z braku odpowiedzi od serwera, a nie z zaginięcia komunikatu. W przypadku retransmitowania komunikatu z zamówieniem, serwer może go otrzymać więcej niż jeden raz, a więc może wykonać operację kilkukrotnie. Jest to dopuszczalne jeśli operacja realizowana przez serwer jest idempotentna, tzn. wykonanie wielokrotne ma taki sam skutek jak jednokrotne.

Problemy gwarancji dostaw Katedra Informatyki Jeśli powtórki komunikatów dochodzą do serwera podczas realizacji zadania (ponieważ jego wykonanie jest bardziej czasochłonne niż limit czasu przewidziany przez klienta), to aby uniknąć powtórzenia operacji, serwer może implementować protokół rejestracji i rozpoznawania zamówień tego samego klienta, w celu odfiltrowania duplikatów o takim samym identyfikatorze zamówienia. Duplikaty będą ignorowane, odpowiedź przesłana po zakończeniu zadania. Jeśli powtórne zamówienie dochodzi po wysłaniu odpowiedzi, serwer może korzystać z rejestru (historii) odpowiedzi. Wyszukując odpowiedź na zamówienie o danym identyfikatorze od danego klienta, serwer retransmituje ponownie komunikat z odpowiedzią, bez konieczności powtórnej realizacji zadania. Strategia ta może być kosztowna pod względem alokacji zasobów. Zazwyczaj serwer przechowuje tylko ostatnią odpowiedź dla danego klienta – przyjście od klienta nowego zamówienia traktowane jest jako potwierdzenie otrzymania odpowiedzi na poprzednie. Jeśli klient nie zgłasza nowych zadań, komunikaty z rejestru odpowiedzi usuwane są ponadto po upływie określonego czasu.

Semantyki niezawodności wywołań RPC Katedra Informatyki Semantyka wywołania ewentualnego. Nie zakłada tolerowania uszkodzeń. Jeśli komunikat z odpowiedzią nie nadejdzie po wyznaczonym czasie i nie ponawia się prób, to nie ma pewności czy procedura została wykonana. Nie wiadomo bowiem, czy zaginął komunikat z zamówieniem lub awarii uległ serwer, czy też wykonanie doszło do skutku, a zaginął komunikat z odpowiedzią. Na ogół trudno taką semantykę zaakceptować. Semantyka wywołania co najmniej jednokrotnego. Retransmitowanie komunikatów odbywa się bez odfiltrowania powtórzeń, tak więc serwer może go otrzymać i wykonać więcej niż raz. Klient w końcu otrzyma odpowiedź, albo zostanie poinformowany, że serwer uległ awarii. Po zakończeniu wywołania RPC serwer nie będzie wiedział ile razy je wykonano. Semantyka ta jest do przyjęcia, jeśli wszystkie procedury serwera mogą być zaprojektowane za pomocą działań idempotentnych.

Semantyki niezawodności wywołań RPC Katedra Informatyki Semantyka wywołania co najwyżej jednokrotnego. Zachodzi odfiltrowywanie powtórzeń oraz retransmitowanie odpowiedzi bez ponownego wykonywania działań. Jeśli serwer nie ulegnie awarii i klient otrzyma wynik wywołania, to procedura została wykonana dokładnie jeden raz. W przeciwnym przypadku następuje sygnalizacja sytuacji wyjątkowej. Tę semantykę wybiera się zazwyczaj w implementacjach RPC, zwłaszcza do realizacji operacji nieidempotentnych.

Sun RPC Katedra Informatyki Jednym z najbardziej znanych uniksowych systemów zdalnych wywołań procedur jest system Sun RPC. Początkowo zaprojektowany został do komunikacji klient/serwer w sieciowym systemie plików Sun NFS. Sun RPC jest załączane jako część rozmaitych systemów operacyjnych firmy Sun i również jest dostępne w innych instalacjach systemu NFS. Programiści maja do wyboru użytkowanie RPC ponad protokołami UDP/IP lub TCP/IP. System Sun RPC zawiera język opisu interfejsu nazywany XDR oraz kompilator interfejsu o nazwie rpcgen.

Język Sun XDR Katedra Informatyki Interfejs identyfikowany jest poprzez tzw. numer programu i numer wersji. Opis interfejsu składa się z definicji procedur, stałych oraz typów. Obok typów prostych, dopuszczalne jest definiowanie struktur, wyliczeń oraz unii. Składnia definicji typów jest taka sama jak w języku C. Definicja procedury określa jej sygnaturę oraz numer (począwszy od 1). Numer zero zarezerwowany jest dla automatycznie generowanej procedury pustej, służącej do testowania dostępności serwera. Dozwolony jest tylko jeden parametr wejściowy. Zarówno typ parametru wejściowego jak i wartości powrotnej mogą mieć charakter prosty lub zmiennej strukturalnej. Procedury wieloparametrowe muszą więc przekazywać parametry jako elementy jednej struktury.

Język Sun XDR const MAX = 100; typedef int plik_id; Katedra Informatyki const MAX = 100; typedef int plik_id; typedef int plik_wsk; typedef int dlugosc; struct Dane { int len; char bufor[MAX]; }; struct pisz_arg { plik_id p; plik_wsk pozycja; Dane dane; struct czyt_arg { plik_id p; plik_wsk pozycja; dlugosc len; }; Program CZYTAJPISZPLIK { version WERSJA { Dane CZYTAJ(czyt_arg) = 1; void PISZ(pisz_arg) = 2; } = 2; } = 9999;

Kompilator rpcgen Kompilator interfejsu rpcgen generuje: Katedra Informatyki Kompilator interfejsu rpcgen generuje: Namiastki procedur klienta. Namiastki procedur serwera, ekspedytora oraz procedurę główną (main) serwera. Procedury XDR przetaczania i odwrotnego przetaczania danych na użytek ekspedytora oraz namiastek klienta oraz serwera. Plik nagłówkowy o nazwie takiej samej jak nazwa interfejsu (programu), np. CzytajPiszPlik.h, z deklaracjami wspólnych zmiennych i typów do użytku w programach klienta i serwera. Sygnatury procedur usługowych podane są w postaci prototypów funkcji języka C. Nazwy procedur są takie same jak w interfejsie, z tym że zamienia się je na małe litery, dodaje znak podkreślenia oraz numer wersji. Argumentem każdej procedury użytkowej jest wskaźnik do jednego argumentu lub struktury zawierającej wszystkie argumenty. Podobnie jest w przypadku wartości powrotnej – zwracany jest wskaźnik do wyniku lub struktury z wynikami.

Program serwera Katedra Informatyki Program serwera implementuje funkcje usługowe, zgodnie z prototypami wygenerowanymi w pliku nagłówkowym przez rpcgen. Wartość powrotna jest wskaźnikiem, musi więc być to adres zmiennej statycznej. Moduł zawierający procedury użytkowe musi zostać skonsolidowany z wygenerowanymi przez rpcgen modułami bibliotecznymi zawierającymi funkcję main, procedurę ekspedytora, i namiastki serwera i procedury przetaczające. Sun RPC działa bez ogólnosieciowych usług wiązania. Zamiast tego udostępnia na komputerze serwera lokalne usługi wiązania, nazywane programami odwzorowania portów (port mapper). Funkcja main tworzy gniazdo do przyjmowania komunikatów z zamówieniami klientów, a następnie eksportuje interfejs usługi, podając lokalnemu programowi odwzorowania portów numer programu (interfejsu), numer wersji oraz identyfikator portu serwera.

Serwer Sun RPC #include <stdio.h> #include <rpc/rpc.h> Katedra Informatyki #include <stdio.h> #include <rpc/rpc.h> #include „CzytajPiszPlik.h” void* pisz_2(pisz_arg* a) { /* kod procedury zapisu*/ } Dane* czytaj_2(czyt_arg* a) { static Dane wynik; /*kod procedury zapisu*/ return &wynik;

Program klienta Katedra Informatyki Moduł zawierający procedury użytkowe musi zostać skonsolidowany z wygenerowanymi przez rpcgen modułami bibliotecznymi zawierającymi namiastki procedur klienta i procedury przetaczające. Do pobrania interfejsu punktu końcowego serwera służy funkcja clnt_create, zwracająca uchwyt klienta zawierający informacje niezbędne do komunikacji z portem serwera. W parametrach podajemy nazwę serwera, numer programu i wersji. Funkcja ta kontaktuje się z usługami odwzorowania portu w celu pobrania pełnej informacji komunikacyjnej. Porty serwerów nie muszą więc być ogólnie znane. Program klienta wywołuje funkcje usługowe, zgodnie z prototypami wygenerowanymi w pliku nagłówkowym przez rpcgen, rozszerzonymi o dodatkowy parametr uchwytu klienta. Semantyka wywołania procedury serwera jest co najmniej jednokrotna. Odstęp czasu miedzy kolejnymi próbami ma wartość domyślną, którą można określić podczas uzyskiwani uchwytu.

Klient Sun RPC #include <stdio.h> #include <rpc/rpc.h> Katedra Informatyki #include <stdio.h> #include <rpc/rpc.h> #include „CzytajPiszPlik.h” main() { CLIENT* client_handle; char* nazwa_serw = ”kkkk”; czyt_arg a; Dane* ptr; client_handle = clnt_create(nazwa_serw, CZYTAJPISZPLIK, WERSJA, ”udp”); if ( client_handle == NULL ) { clnt_pcreateerror(nazwa_serw); exit(1); } a.p = 10; a.pozycja = 100; a.len = 1000; ptr = czytaj_2(&a, client_handle); clnt_destroy(client_handle);

DCE RPC Katedra Informatyki DCE (Distributed Computing Environment) jest rozproszonym środowiskiem obliczeniowym, opracowanym przez konsorcjum OSF (Open Software Foundation – obecnie Open Software Group). DCE opracowane początkowo dla systemu UNIX zostało przeniesione do wszystkich głównych systemów operacyjnych, łącznie z systemami VMS, Windows, a także systemami operacyjnymi komputerów osobistych. Specyfikacje DCE RPC zostały zaadaptowane przez Microsoft jako podstawowy system obliczeń rozproszonych. Wiele modeli obiektów rozproszonych stanowi bezpośrednie rozwinięcie koncepcji zawartych w DCE RPC.

DCE RPC Katedra Informatyki Interfejs specyfikowany jest z wykorzystaniem specjalnego języka o nazwie IDL. Pliki IDL zawierają deklaracje prototypów funkcji specyfikowane w formie zbliżonej do składni języka C. Zawierać mogą również deklaracje typów, stałych oraz informacje inne potrzebne do przetaczania parametrów i wyników. Interfejs DCE RPC identyfikowany jest przez jednoznaczny identyfikator UID, składający się ze 128 bitowej liczby dwójkowej. Identyfikatory UID generowane są przez generator uuidgen, na podstawie informacji o lokalizacji komputera oraz czasu. Wiązanie w DCE RPC ma charakter lokalny, tzn. środowisko utrzymuje na maszynie serwera proces zwany demonem DCE (DCE daemon), wykonujący usługę odwzorowania portów. Środowisko DCE dostarcza jednak również globalnych usług wiązania. Serwer RPC może zostać zarejestrowany w globalnej usłudze katalogowej.

DCE RPC Katedra Informatyki Usługi DCE RPC realizowane mogą być na bazie różnych protokołów. Domyślna semantyka wywołania procedury zdalnej ma charakter co najwyżej jednokrotny. Procedura może zostać jednak oznaczona w pliku IDL jako idempotentna. Wówczas wywołana będzie co najmniej jednokrotnie.

Przykład: Korzystanie z DCE RPC w systemie Windows Katedra Informatyki Generujemy pusty plik interfejsu przy użyciu programu uuidgen z opcją /I. W naszym przykładzie będzie to plik motd.idl. Modyfikujemy otrzymany plik IDL, definiując interfejs usługi. Zmieniamy nazwę interfejsu na MOTD, deklarujemy procedurę zdalną GetMOTD. Opis funkcji jest w zasadzie taki sam jak w C. W nawiasach kwadratowych informujemy kompilator interfejsu jak mają być traktowane parametry. Opisy te nazywamy atrybutami. uuid(9ebec1c7-bb8a-4063-ac06-d6441c6badea), version(1.0) ] interface MOTD { void GetMOTD([out, string, max_is(ct)] char* msg, [in] unsigned int ct); }

Przykład: Korzystanie z DCE RPC w systemie Windows Katedra Informatyki Istnieje wiele innych atrybutów, które można użyć do opisu innych typów parametrów (np. takich jak tablice). Można również definiować własne typy. Parametry mogą być również jednocześnie wejściowe i wyjściowe. Należy jednak robić tak jedynie w przypadku gdy rzeczywiście potrzebny nam jest przepływ danych w obie strony. Pozwoli to uniknąć przetaczania przez sieć śmieci. uuid(9ebec1c7-bb8a-4063-ac06-d6441c6badea), version(1.0) ] interface MOTD { void GetMOTD([out, string, max_is(ct)] char* msg, [in] unsigned int ct); }

Przykład: Korzystanie z DCE RPC w systemie Windows Katedra Informatyki Tworzymy nowy, pusty plik o takiej samej nazwie jak plik IDL i rozszerzeniu ACF. Będzie on zawierał linię tworzącą niejawny uchwyt używany przez mechanizm RPC dla naszego interfejsu. [implicit_handle (handle_t MOTDHandle)] interface MOTD {}

Przykład: Korzystanie z DCE RPC w systemie Windows Katedra Informatyki Kompilujemy stworzony interfejs z wykorzystaniem programu MIDL. Tworzy on plik nagłówkowy motd.h, który włączany będzie zarówno do kodu klienta jak i serwera, oraz dwa pliki motd_c.c (plik funkcji pośrednich po stronie klienta) i motd_s.c (funkcje pośrednie po stronie serwera). Piszemy kod serwera. Do projektu włączamy również plik motd_s.c oraz rpcrt4.lib – bibliotekę zawierającą funkcje środowiska RPC. Piszemy kod klienta. Konsolidujemy go z plikiem modt_c.c oraz również z biblioteką rpcrt4.lib.

Serwer RPC dla Windows – przydatne funkcje Katedra Informatyki RPC_STATUS RPC_ENTRY RpcServerUseProtseqEp( //definiuje punkt końcowy unsigned char *Protseq, // Identyfikator protokołu unsigned int MaxCalls, // Długość kolejki wywołań unsigned char *Endpoint, // Id. punktu końcowego (numer gniazda, id potoku) void *SecurityDescriptor //Deskryptor zabezpieczeń (tylko potoki) ); Protseq Identyfikator (tekstowy) protokołu, np. ”ncacn_np” dla nazwanych potoków, ”ncacn_ip_tcp” dla tcp. Endpoint Identyfikator (tekstowy) punktu końcowego, np. dla ”ncacn_np” identyfikator potoku, dla ”ncacn_ip_tcp” numer gniazda.

Serwer RPC dla Windows – przydatne funkcje Katedra Informatyki RPC_STATUS RPC_ENTRY RpcServerRegisterIf( //rejestracja interfejsu RPC_IF_HANDLE IfSpec, // uchwyt interfejsu (wygenerowany przez MIDL) UUID *MgrTypeUuid, // UUID menedżera interfejsu (zazwyczaj NULL) RPC_MGR_EPV *MgrEpv // Menedżer interfejsu (NULL to defaultowy // wygenerowany przez MIDL) ); RPC_STATUS RPC_ENTRY RpcServerListen( //start nasłuchiwania unsigned int MinimumCallThreads, // Min. liczba wątków serwera (zazw. 1) unsigned int MaxCalls, // Max liczba jednoczesnych k;ientów unsigned int DontWait // Zazwyczaj 0 );

Serwer RPC dla Windows (1) Katedra Informatyki #include <stdio.h> #include <stdlib.h> #include "motd.h" void main() { RPC_STATUS status; unsigned int cMaxCalls = 20; //dla gniazd //status = RpcServerUseProtseqEp((unsigned char*)"ncacn_ip_tcp", // cMaxCalls, (unsigned char*)"201", NULL); status = RpcServerUseProtseqEp((unsigned char*)"ncacn_np", cMaxCalls, (unsigned char*)"\\pipe\\MOTD", NULL); if ( status ) { exit(status); } status = RpcServerRegisterIf(MOTD_v1_0_s_ifspec, NULL, NULL); status = RpcServerListen(1, cMaxCalls, 0); }

Serwer RPC dla Windows (2) Katedra Informatyki 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);

Serwer RPC dla Windows (3) Katedra Informatyki static char *motd[]= { "Yawn a more Roman way", "Rats live on no evil star.", "If I had a hi-fi", "Rise to vote sir", "Evil Olive", "Never odd or even", "No lemons, no melon" }; /* Funkcja(e)*/ void GetMOTD(unsigned char __RPC_FAR *msg, unsigned int ct) { static int n=0; char tmp[1024]; sprintf(tmp,"%d: %s",++n,motd[n%(sizeof(motd)/sizeof(char *))]); strncpy((char*)msg,tmp,ct); }

Klient RPC dla Windows – przydatne funkcje Katedra Informatyki RPC_STATUS RPC_ENTRY RpcStringBindingCompose( unsigned char *ObjUuid, // Ident. interfejsu unsigned char *ProtSeq, // Ident. protokołu unsigned char *NetworkAddr, // Adres sieciowy komputera unsigned char *EndPoint, // Id. punktu końcowego unsigned char *Options, // Opcje unsigned char **StringBinding // Łańcuch połączenia (parametr wyjściowy) ); Protseq Identyfikator (tekstowy) protokołu, np. ”ncacn_np” dla nazwanych potoków, ”ncacn_ip_tcp” dla tcp. NetworkAddr Adres sieciowy komputera serwera, np. dla ”ncacn_np” nazwa Windows, dla ”ncacn_ip_tcp” adres IP lub nazwa domenowa. Endpoint Identyfikator (tekstowy) punktu końcowego, np. dla ”ncacn_np” identyfikator potoku, dla ”ncacn_ip_tcp” numer gniazda.

Klient RPC dla Windows – przydatne funkcje Katedra Informatyki RPC_STATUS RPC_ENTRY RpcBindingFromStringBinding( unsigned char *StringBinding, // Łańcuch połączenia RPC_BINDING_HANDLE *Binding // Adres uchwytu klienta ); RPC_STATUS RPC_ENTRY RpcStringFree( unsigned char **String ); RPC_STATUS RPC_ENTRY RpcBindingFree( RPC_BINDING_HANDLE *Binding );

Klient RPC dla Windows (1) Katedra Informatyki #include <stdio.h> #include <stdlib.h> #include "motd.h" unsigned char* pszStringBinding = NULL; RPC_STATUS RPC_init(int argc, char* argv[]) { RPC_STATUS status; unsigned char* pszNetworkAddres = NULL; if ( argc ==2 ) pszNetworkAddres = (unsigned char*)argv[1]; // Dla gniazd // status = RpcStringBindingCompose(NULL, (unsigned char*)"ncacn_ip_tcp", // pszNetworkAddres, (unsigned char*)"201", // NULL, &pszStringBinding); status = RpcStringBindingCompose(NULL, (unsigned char*)"ncacn_np", pszNetworkAddres, (unsigned char*)"\\pipe\\MOTD", NULL, &pszStringBinding); if ( status ) {return status;} status = RpcBindingFromStringBinding(pszStringBinding, &MOTDHandle); return status; }

Klient RPC dla Windows (2) Katedra Informatyki RPC_STATUS RPC_close() { RPC_STATUS status; status = RpcStringFree(&pszStringBinding); if ( status ) {return status;} status = RpcBindingFree(&MOTDHandle); return status; } 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);

Klient RPC dla Windows (3) Katedra Informatyki void main(int argc, char* argv[]) { unsigned long ulCode; char msg[100]; RPC_STATUS status = RPC_init(argc, argv); if ( status ) { printf("Blad laczenia z RPC\n"); exit(status); } GetMOTD((unsigned char*)msg, sizeof(msg)); printf("Z serwera: %s\n", msg); status = RPC_close(); if ( status ) { exit(status);}

Klient RPC dla Windows (4) – Przechwytywanie wyjątków RPC Katedra Informatyki void main(int argc, char* argv[]) { unsigned long ulCode; char msg[100]; RPC_STATUS status = RPC_init(argc, argv); if ( status ) { printf("Blad laczenia z RPC\n"); exit(status); } RpcTryExcept { GetMOTD((unsigned char*)msg, sizeof(msg)); printf("Z serwera: %s\n", msg); RpcExcept(1) { ulCode = RpcExceptionCode(); printf("Runtime reported exception 0x%lx = %ld\n", ulCode, ulCode); RpcEndExcept status = RPC_close(); if ( status ) { exit(status);}