Huruvida fjärranrop rpc är möjligt. Fjärrprocedurer


Tanken bakom Remote Procedure Call (RPC) är att utöka den välkända och välkända mekanismen för att överföra kontroll och data inom ett program som körs på en enda maskin för att överföra kontroll och data över ett nätverk. Det vill säga, klientapplikationen får åtkomst till procedurer lagrade på servern. Fjärrproceduranropsfaciliteter är utformade för att underlätta organisationen av distribuerad datoranvändning. Den mest effektiva användningen av RPC uppnås i de applikationer där det finns interaktiv kommunikation mellan fjärrkomponenter med korta svarstider och relativt lite dataöverföring. Sådana applikationer kallas RPC-orienterade.

De karakteristiska egenskaperna hos RPC är:

Asymmetri, det vill säga en av de interagerande parterna är initiativtagaren;

Synkronicitet, det vill säga exekveringen av anropsproceduren avbryts från det ögonblick då begäran utfärdas och återupptas först efter att ha återvänt från den anropade proceduren.

Det finns flera implementeringar av fjärranropsprocedurer på olika operativsystem. Operativsystemet UNIX använder en procedur med samma namn (Remote Procedure Call - RPC). Denna procedur är inbäddad i systemets kärna. Dess utförande tillhandahålls av RPC-protokollet. I Windows-operativsystem började RPC utvecklas på basis av OLE-mekanismer, som gradvis utvecklades till DCOM-tekniken (Distributed Component Object Model). Denna teknik låter dig skapa en ganska kraftfull distribuerad nätverksdatormiljö. Tekniken använder proprietära Microsoft-protokoll.

Hur RPC fungerar

Innan ett direktanrop på klient- och serversidan måste speciella strukturer (procedurer, filer) skapas - dessa är den så kallade klientstubben och serverskelettet, som är nödvändiga för korrekt drift av RPC. Oftast genereras de automatiskt av speciella verktyg från huvudprogramkoden.

När ett fjärranrop sker i ett distribuerat system, sker följande åtgärder:

1. Klientproceduren kallar stubben som en normal procedur. Stab packs parametrar (marshaling).

2. Stab hänvisar till OS-kärnan.

3. Kärnan skickar ett meddelande till fjärrdatorn (kärnan på fjärrdatorn).

4. Överföring av det mottagna meddelandet till skelettet av serverprocessen.

5. Uppackning av parametrar (unmarsharing, unmarsharing). Anropar den nödvändiga proceduren.

6. Proceduren utförs på servern. Returnerar resultaten till skelettet.

7. Skelett packar resultatet.

8. Skickar resultatet till kärnan.

9. Serverkärnan skickar meddelandet över nätverket till klientkärnan.

10. Klientens kärna adresserar stubben. Stub packar upp resultatet.

11. Överför från stubben till klientprocessen.

Windows Remote Procedure Call-tjänst (RPC).

För att förstå vikten av RPC, överväg åtminstone en lista över verktyg och tjänster som inte fungerar utan RPC i Windows 2000. Faktum är att avaktivering av RPC-tjänsten i den här miljön gör att hela systemet kraschar. Så tjänsten "Remote Procedure Call (RPC)" beror på:

1. Telnet - Tillåter en fjärranvändare att logga in och köra konsolprogram med hjälp av kommandoraden.

2. Windows Installer - Installerar, avinstallerar eller reparerar programvara enligt instruktionerna i MSI-filerna.

3. IPSEC Policy Agent - Hanterar IP Security Policy och kör ISAKMP / Oakley (IKE) och IP Security Driver.

4. Print Spooler - laddar filer till minnet för senare utskrift.

5. Säker lagring - Ger säker lagring av känslig data, såsom privata nycklar, för att förhindra obehörig åtkomst till tjänster, processer eller användare.

6. Windows Management Instrumentation - Ger information om systemhantering.

7. Changed Links Tracking Client - Skickar meddelanden om filer som flyttats mellan NTFS-volymer i nätverksdomänen.

8. Distributed Transaction Coordinator - Koordinering av transaktioner som är distribuerade över flera databaser, meddelandeköer, filsystem eller andra säkra transaktionsresurshanterare.

9. Routing och Remote Access - erbjuder routingtjänster till organisationer i lokala och globala nätverk.

10. Task Scheduler - låter dig köra program vid en viss tidpunkt.

11. Nätverksanslutningar - hanterar objekten i mappen "Nätverk och uppringt nätverk", som visar egenskaperna för det lokala nätverket och uppringda anslutningar.

12. COM + Event System - Automatisk spridning av händelser till prenumererande COM-komponenter.

13. Indexeringstjänst - Indexering för snabba sökningar.

14. Meddelandetjänst - skickar och tar emot meddelanden som skickats av administratörer eller aviseringstjänst.

15. Faxtjänst - Hjälper dig att skicka och ta emot faxmeddelanden.

16. Flyttbar lagring - Hanterar flyttbara media, enheter och bibliotek.

17. Telefoni - ger stöd för Telephony API (TAPI) för program som styr telefonutrustning och röst IP-anslutningar på denna dator, samt via ett LAN - på servrar där motsvarande tjänst körs.

RMI-applikationer

Remote Method Invocation (RMI) är en implementering av RPC-idéer för programmeringsspråket Java.

RMI är en JavaSoft-produkt utvecklad för Java och integrerad i JDK 1.1 och högre. RMI implementerar en distribuerad datormodell och tillhandahåller ett kommunikationsmedel mellan Java-program (virtuella Java-maskiner) som körs på en eller flera fjärrdatorer. RMI tillåter klient- och serverapplikationer över nätverket att anropa metoder på klienter/servrar som körs på virtuella Java-maskiner. Den största fördelen med RMI är att det ger programmeraren ett programmerbart gränssnitt på högre nivå som gör att en referens till ett fjärrobjekt kan skickas som ett argument eller returneras som ett resultat. RMI kräver att Java-program körs i båda ändarna av anslutningen. Nätverksanslutningen uppnås med TCP/IP-protokollet. RMI-arkitekturen visas i fig. "RMI-arkitektur".

Client Stub (en adapter för klienten - någon enhet på klienten som tillhandahåller mottagnings-/sändningsfunktioner), och Server Skeleton (en adapter för servern - någon enhet på servern som hanterar fjärranrop) härleds från ett gemensamt gränssnitt, men skiljer sig genom att klientstubben bara används för att ansluta till RMI-registret och serverstubben används för att kommunicera direkt med serverfunktioner.

RMI är faktiskt en ny typ av objektförfråganmäklare som bygger på Java Object Model. Precis som ORB introducerar RMI fem nyckelpunkter:

1. Låter dig flytta kod utöver data.

2. Säkerställer praktiskt taget säkerheten vid exekvering av den laddade koden.

3. Tillåter att objekt skickas efter värde.

4. Använder Java som gränssnittsdefinitionsspråk och som implementeringsspråk.

5. Använder ett Uniform Resource Locator (URL)-baserat namnschema.

Detta konverterar objekt till en seriell form - till en ström av bytes som överförs som en parameter i ett meddelande med hjälp av TCP/IP-protokollet.

RMI:er kan delas in i fyra kategorier:

RMI-kärna - definierar de gränssnitt som krävs för att göra anrop till fjärrmetoder;

RMI-namntjänst - definierar gränssnitt och klasser som låter dig få referenser till serverobjekt efter namn;

RMI-säkerhet - definierar en ny RMI-säkerhetshanterare och klassladdningsgränssnitt (RMI utökar on-demand Java-klassladdningsmekanismen för stubbladdning);

Marshalling (linda en begäran, inklusive parametrar, returvärde, själva begäran, till ett standardformat som är lämpligt för överföring över nätverket) - RMI definierar lågnivågränssnitt för rangering av fjärrobjekt, som används för att skriva Java-objekt till en ström och att läsa ett objekt från en ström.

JavaSoft och OMG arbetar för att föra RMI- och CORBA-objektmodellerna närmare varandra. Denna konvergens sker inom två områden:

RMI över IIOP. JavaSoft utvecklar en version av RMI som körs ovanpå IIOP-transporten. IIOP ger RMI följande fördelar:

1. Inbyggt stöd för transaktionsspridning.

2. Stöd för ORB-baserad brandvägg med IIOP-proxy (ingen HTTP-tunnling).

3. Interaktion med objekt skrivna på andra språk genom en delmängd av RMI / IDL.

4. Öppen standard för distribuerade objekt.

RMI / IDL. CORBA Java-standarden i IDL är CORBA / RMI-konvergensstandarden. Det tillåter Java-programmerare att definiera CORBA-gränssnitt med Java RMI-semantik istället för CORBA IDL. Kompilatorn använder denna semantik för att automatiskt generera CORBA IDL, stubbar och skelett. En delmängd av RMI / IDL gör att RMI-program kan anropas av CORBA flerspråkiga klienter som använder IIOP; det tillåter också RMI-program att anropa CORBA-objekt skrivna på andra språk.

RMI över IIOP verkar vara en bra CORBA / Java-lösning eftersom den kombinerar två kraftfulla teknologier. Den största fördelen med RMI är att den kan användas för att snabbt och enkelt skapa ett litet distribuerat system i en ren Java-miljö. Den största nackdelen med RMI är oförmågan att integrera denna mekanism med befintliga applikationer.

Jämförelse av distribuerade och icke-distribuerade Java-program

RMI-designerna strävade efter att använda distribuerade Java-objekt på samma sätt som att använda lokala objekt. Följande tabell listar några viktiga skillnader.

RMI-gränssnitt

RMI-arkitekturen är baserad på en viktig princip: definitionen av beteende och implementeringen av det beteendet betraktas som olika begrepp. RMI gör det möjligt att dela upp och exekvera på olika JVM:er koden som definierar beteendet och koden som implementerar beteendet.

Detta uppfyller kraven för distribuerade system där klienter är medvetna om tjänstedefinitioner och servrar tillhandahåller dessa tjänster. Specifikt i RMI kodas definitionen av en fjärrtjänst med hjälp av ett Java-gränssnitt. Fjärrtjänstimplementeringen är kodad i klassen. Därför är nyckeln till att förstå RMI att komma ihåg att gränssnitt definierar beteende och klasser definierar implementering.

Kom ihåg att Java-gränssnitt inte innehåller körbar kod. RMI stöder två klasser som implementerar samma gränssnitt. Den första klassen är implementeringen av beteendet och exekveras på servern. Den andra klassen fungerar som ett mellanliggande gränssnitt för fjärrtjänsten och körs på klientdatorn.

Klientprogrammet anropar proxyobjektets metoder, RMI skickar begäran till fjärr-JVM och dirigerar den till objektets implementering. Alla värden som returneras från implementeringen skickas tillbaka till proxyn och sedan till klientprogrammet.

RMI-arkitekturlager

RMI-implementeringen består i huvudsak av tre abstrakta lager. Den första är stubben och skelettnivån, som ligger direkt framför utvecklaren. Detta lager fångar upp metodanrop som görs av klienten med hjälp av en gränssnittsreferensvariabel och vidarebefordrar dem till fjärr-RMI-tjänsten.

Nästa nivå är nivån för fjärrlänken. Detta lager förstår hur man tolkar och hanterar referenser till fjärrtjänstobjekt. I JDK 1.1 ansluter detta lager klienter till fjärrtjänstobjekt som körs på servern. Denna anslutning är en en-till-en länk (enkelriktad länk). I Java 2 SDK har detta lager utökats för att stödja aktivering av passiva fjärrobjekt med hjälp av Remote Object Activation-teknik.

Transportskiktet är baserat på TCP/IP-anslutningar mellan nätverksanslutna maskiner. Det ger grundläggande anslutningar och vissa anti-manipuleringsstrategier. När du använder en skiktad arkitektur kan var och en av skikten ändras eller ersättas utan att det påverkar resten av systemet. Till exempel kan transportlagret ersättas av UDP/IP utan att resten av lagren ändras.

Sök efter borttagna objekt

När man tittar på RMI-arkitekturen är frågan: "Hur hittar klienten fjärr-RMI-tjänsten?" Klienter hittar fjärrtjänster med hjälp av en namn- eller katalogtjänst. Hur kan en kund hitta en tjänst med hjälp av tjänsten? Men det är det verkligen. Namn- eller katalogtjänsten körs på en välkänd värd och har ett välkänt portnummer (välkänd betyder att alla i organisationen känner till det).

RMI kan använda många olika katalogtjänster, inklusive Java Naming and Directory Interface (JNDI). RMI själv innehåller en enkel tjänst som kallas RMI-registret, rmiregistry. RMI-registret körs på varje maskin som innehåller fjärrtjänstobjekt och accepterar serviceförfrågningar, med port 1099 som standard. På värden skapar serverprogrammet en fjärrtjänst genom att först skapa ett lokalt objekt som implementerar tjänsten. Den exporterar sedan detta objekt till RMI. När objektet har exporterats skapar RMI en lyssnartjänst som väntar på en klientanslutning och en tjänsteförfrågan. Efter exporten registrerar servern objektet i RMI-registret med det offentliga namnet.

På klientsidan nås RMI-registret genom den statiska klassen Namngivning. Den tillhandahåller en uppslagsmetod () som klienten använder för att fråga registret. Uppslagsmetoden () accepterar en URL som pekar på värdnamnet och namnet på den begärda tjänsten. Metoden returnerar en fjärrreferens till det betjänande objektet. URL:en ser ut så här:

rmi: // [:] /
där värdnamn är ett namn som känns igen på det lokala nätverket (LAN) eller DNS-namnet på Internet. Du behöver bara ange name_service_port om namntjänsten körs på en annan port än standardporten 1099.

Använder RMI

Ett fungerande RMI-system består av flera delar: definiera gränssnitt för fjärrtjänster, implementera fjärrtjänster, stubb- och skelettfiler, en server som tillhandahåller fjärrtjänster, en RMI-namntjänst som gör det möjligt för klienter att hitta fjärrtjänster, en klassfilleverantör (HTTP eller FTP server ), ett klientprogram som behöver fjärrtjänster.

Förutsatt att RMI-systemet redan är designat måste följande steg vidtas för att skapa det:

1. Skriv och kompilera Java-kod för gränssnitt.

2. Skriv och kompilera Java-kod för implementeringsklasserna.

3. Skapa stub- och skelettklassfiler från implementeringsklasser.

4. Skriv Java-kod för värdprogrammet för fjärrservice.

5. Utveckla Java-kod för RMI-klientprogrammet.

6. Installera och kör RMI-systemet.

Exempel på RMI - applikationer

Det första steget är att skriva och kompilera Java-kod för tjänstens gränssnitt. Kalkylatorns gränssnitt definierar alla fjärrfunktioner som erbjuds av tjänsten:

offentligt gränssnitt Calculator utökar java.rmi.Remote (
public long add (långt a, långt b) kastar java.rmi.RemoteException;
public long sub (långt a, långt b) kastar java.rmi.RemoteException;
public long mul (långt a, långt b) kastar java.rmi.RemoteException;
offentlig lång div (långt a, långt b) kastar java.rmi.RemoteException;
}

Observera att det här gränssnittet utökar fjärrgränssnittet, och signaturen för varje metod anger att den kan skicka ett RemoteException-objekt. I allmänhet kallas ett objekt för fjärr om det implementerar fjärrgränssnittet. "Implements" i betydelsen av titeln (public interface Calculator utökar java.rmi.Remote), det finns inga metoder i detta gränssnitt. Detta är en etikett. Nu måste vi skriva implementeringen av fjärrtjänsten. Nedan är CalculatorImpl-klassen:

public class CalculatorImpl utökar java.rmi.server.UnicastRemoteObject
implementerar kalkylator (
// Implementeringar måste ha en explicit konstruktör för att kunna deklarera
// Exception RemoteException
public CalculatorImpl ()
kastar java.rmi.RemoteException (
super ();
}
public long add (långt a, långt b) kastar java.rmi.RemoteException (
returnera a + b;
}
public long sub (långt a, långt b) kastar java.rmi.RemoteException (
returnera a - b;
}
public long mul (långt a, långt b) kastar java.rmi.RemoteException (
returnera a * b;
}
offentlig lång div (långt a, långt b) kastar java.rmi.RemoteException (
returnera a / b;
}
}

Implementeringsklassen använder Unicast RemoteObject för att koppla till RMI-systemet. I det här exemplet utökar implementeringsklassen UnicastRemoteObject direkt. Detta är valfritt. En klass som inte utökar UnicastRemoteObject kan använda sin exportObject-metod () för att koppla till RMI. Om en klass utökar UnicastRemoteObject måste den tillhandahålla en konstruktor som förklarar att den kan kasta ett RemoteException-objekt. Om den här konstruktören anropar metoden super() anropar den koden i UnicastRemoteObject som utför RMI-anslutningen och initierar fjärrobjektet.

Fjärrstyrda RMI-tjänster måste placeras i serverprocessen. Klassen CalculatorServer är en mycket enkel server som tillhandahåller enkla element att vara värd för.

importera java.rmi.Naming;

public class CalculatorServer (
public CalculatorServer () (
Prova (
Calculator c = new CalculatorImpl ();
Naming.rebind ("
rmi: // localhost: 1099 /
CalculatorService ", c);
) fånga (Undantag e) (
System.out.println ("Problem:" + e);
}
}
ny CalculatorServer ();
}
}

Klientens källkod kan till exempel vara följande:

importera java.rmi.Naming;
importera java.rmi.RemoteException;
importera java.net.MalformedURLException;
importera java.rmi.NotBoundException;
offentlig klass CalculatorClient (
public static void main (String args) (
Prova (
Miniräknare c = (Kalkylator)
Naming.lookup (
"rmi: // fjärrvärd
/ CalculatorService ");
System.out.println (c.sub (4, 3));
System.out.println (c.add (4, 5));
System.out.println (c.mul (3, 6));
System.out.println (c.div (9, 3));
}
catch (MalformedURLEexception murle) (
System.out.println ();
System.out.println (
"MalformedURLEexception");
System.out.println (murle);
}
catch (RemoteException re) (
System.out.println ();
System.out.println (
"RemoteException");
System.out.println (re);
}
catch (NotBoundException nbe) (
System.out.println ();
System.out.println (
"NotBoundException");
System.out.println (nbe);
}
fånga (
java.lang.ArithmeticException
ae) (
System.out.println ();
System.out.println (
"java.lang.ArithmeticException");
System.out.println (ae);
}
}
}

Nu kan du starta systemet. Detta kan göras (efter att ha mottagit motsvarande klassfiler och placerat dem på samma eller olika datorer) så här:

1. Starta RMI-registret ("rmiregistry").

2. Starta servern ("java CalculatorServer").

3. Starta klienten ("java CalculatorClient").

Om allt går bra kommer du att se följande information:

1
9
18
3

Det var allt - ett fungerande RMI-system är klart. Även om du kör tre konsoler på samma maskin, använder RMI ditt nätverks TCP/IP-stack för att kommunicera mellan tre separata JVM. Det är ett komplett RMI-system.

Distribuera RMI-klasser

För att köra en RMI-applikation måste de stödjande klassfilerna finnas på platser där de kan hittas av servern och klienterna.

Följande klasser måste vara tillgängliga för servern (för klassladdaren):

Implementeringar av fjärrtjänster

Skelett för implementeringsklasser (endast för servrar baserade på JDK 1.1)

Stubbar för implementeringsklasser

Alla andra serverklasser

Klasser bör vara tillgängliga för klienten (för klassladdaren):

Definitioner av fjärrtjänstgränssnitt

Stubbar för klasser som implementerar en fjärrtjänst

Serverklasser för objekt som används av klienten (som returvärde)

Alla andra kundklasser

När du väl vet vilka filer som ska placeras på olika noder i nätverket är det enkelt att göra dem tillgängliga för varje JVM-klassladdare.

Distribuerad sophämtning

En av fördelarna med programmering för Java-plattformen är att du inte oroar dig för minnesallokering. JVM har en automatisk sophämtare som frigör minne som upptas av alla objekt som inte längre används av det körande programmet. Ett av designkraven för RMI var dess sömlösa integration i programmeringsspråket Java, inklusive sophämtning. Att designa en effektiv sophämtare för en enda maskin är en skrämmande uppgift; att utveckla en distribuerad sophämtare är en mycket svår uppgift. RMI-systemet tillhandahåller en referensräknande distribuerad sophämtningsalgoritm baserad på nätverksobjekt som används i Modula-3. Detta system håller, medan det körs, reda på vilka klienter som har begärt åtkomst till fjärrobjekt som körs på servern. När en länk visas markerar servern objektet som smutsigt, och när klienten tar bort länken flaggas objektet som rent.

Gränssnittet till DGC (distributed garbage collector) är dolt på stubb- och skelettnivå. Fjärrobjektet kan dock implementera gränssnittet java.rmi.server.Unreferenced och meddelas via metoden utan referens när det inte finns någon annan klient som innehåller en livereferens. Utöver länkräkningsmekanismen har livelänken i klienten en hyresperiod med en angiven tid. Om klienten inte förnyar anslutningen till fjärrobjektet innan hyresavtalet löper ut anses länken vara död och fjärrobjektet kan återtas av sophämtaren. Hyrestiden styrs av java.rmi.dgc.leaseValue-systemegenskapen. Dess värde anges i millisekunder och är som standard lika med 10 minuter. På grund av denna sopsamlingssemantik måste klienten vara beredd att hantera föremål som kan "försvinna".

Slutsats

Remote Method Invocation (RMI)-teknik, som först introducerades i JDK 1.1, har tagit nätverksprogrammering till nästa nivå. Även om RMI är relativt lätt att använda och inte utan sina nackdelar, är det en otroligt kraftfull teknik och öppnar upp ett helt nytt paradigm för den genomsnittliga Java-programmeraren - världen av distribuerad objektberäkning.


Fjärrproceduranrop(eller Ringer fjärrprocedurer) (från engelskan. Remote Procedure Call (RPC)) är en klass av teknologier som tillåter datorprogram att anropa funktioner eller procedurer i ett annat adressutrymme (vanligtvis på fjärrdatorer). Vanligtvis inkluderar en implementering av RPC-teknik två komponenter: ett nätverksprotokoll för klient-serverutbyte och ett objektserialiseringsspråk (eller strukturer, för icke-objekt-RPC). Olika RPC-implementationer har väldigt olika arkitekturer och möjligheter: vissa implementerar SOA, andra CORBA eller DCOM. I transportlagret används RPC främst av TCP- och UDP-protokollen, men vissa är baserade på HTTP (vilket bryter mot ISO / OSI-arkitekturen, eftersom HTTP inte ursprungligen var ett transportprotokoll).

Genomförande

Det finns många tekniker som tillhandahåller RPC:

  • Sun RPC (binärt protokoll baserat på TCP och UDP och XDR) RFC-1831 även känd som ONC RPC RFC-1833
  • .Net Remoting (binärt protokoll baserat på TCP, UDP, HTTP)
  • SOAP - Simple Object Access Protocol se specifikation: RFC-4227
  • XML RPC (HTTP Based Text Protocol) Se specifikation: RFC-3529
  • Java RMI - Java Remote Method Invocation - se spec: http://java.sun.com/j2se/1.5.0/docs/guide/rmi/index.html
  • JSON-RPC JavaScript Object Notation Remote Procedure Calls (HTTP-baserat textprotokoll) Se specifikation: RFC-4627
  • DCE / RPC - Distributed Computing Environment / Remote Procedure Calls (binärt protokoll baserat på olika transportprotokoll, inklusive TCP / IP och Named Pipes från SMB / CIFS-protokoll)
  • DCOM - Distributed Component Object Model känd som MSRPC Microsoft Remote Procedure Call eller "Network OLE" (en objektorienterad förlängning av DCE RPC som låter dig skicka referenser till objekt och anropsmetoder för objekt genom sådana referenser)

Princip

Tanken bakom Remote Procedure Call (RPC) är att utöka den välkända och välkända mekanismen för att överföra kontroll och data inom ett program som körs på en enda maskin för att överföra kontroll och data över ett nätverk. Fjärrproceduranropsfaciliteter är utformade för att underlätta organisationen av distribuerad datoranvändning och skapandet av distribuerade klient-serverinformationssystem. Den största effektiviteten av att använda RPC uppnås i de applikationer där det finns en interaktiv kommunikation mellan fjärrkomponenter med kort svarstid och en relativt liten mängd överförd data. Sådana applikationer kallas RPC-orienterade.

Att implementera fjärrsamtal är mycket mer komplext än att implementera lokala procedursamtal. Följande problem och uppgifter kan identifieras som måste lösas vid implementering av RPC:

  • Eftersom anroparen och den anropade proceduren exekveras på olika maskiner, har de olika adressutrymmen, och detta skapar problem vid överföring av parametrar och resultat, särskilt om maskinerna kör olika operativsystem eller har olika arkitekturer (till exempel big eller big endian ). Eftersom RPC inte kan räkna med delat minne betyder det att RPC-parametrar inte får innehålla pekare till icke-stackminnesplatser och att parametervärden måste kopieras från en dator till en annan. För att kopiera procedurparametrarna och resultatet av deras exekvering över nätverket serialiseras de.
  • Till skillnad från ett lokalt samtal använder ett fjärranrop nödvändigtvis nätverksarkitekturens transportlager (till exempel TCP), men detta förblir dolt för utvecklaren.
  • Exekveringen av det anropande programmet och den anropade lokala proceduren på samma maskin görs i en enda process. Men det finns minst två processer involverade i RPC-implementering - en på varje maskin. Om en av dem avslutas onormalt kan följande situationer uppstå: om anropsproceduren kraschar kommer de fjärranropade procedurerna att bli "föräldralösa", och om fjärrprocedurerna avslutas onormalt kommer anropsprocedurerna att bli "berövade föräldrar" av anropsprocedurerna , som förgäves väntar på svar från fjärrprocedurerna.
  • Det finns ett antal problem förknippade med heterogeniteten hos programmeringsspråk och driftsmiljöer: datastrukturer och strukturer för proceduranrop som stöds i ett programmeringsspråk stöds inte på samma sätt på alla andra språk. Det finns alltså ett kompatibilitetsproblem som ännu inte har lösts vare sig genom införandet av en allmänt accepterad standard eller genom implementering av flera konkurrerande standarder i alla arkitekturer och på alla språk.

Delsystem

  • Transportdelsystem

Hantering av utgående och inkommande anslutningar. - Stöd för konceptet "meddelandegräns" för transportprotokoll som inte direkt stöder det (TCP). - Stöd för garanterad leverans för transportprotokoll som inte direkt stöder det (UDP).

  • Trådpool (kallad endast sida). Tillhandahåller en exekveringskontext för kod som anropas över nätverket.
  • Marshaling (även kallad "serialisering"). Packa anropsparametrar i en byteström på ett standardsätt som inte beror på arkitekturen (särskilt på byteordningen i ett ord). I synnerhet kan arrayer, strängar och strukturer som pekas på av pekparametrar exponeras för det.
  • Paketkryptering och digitala signaturer.
  • Autentisering och auktorisering. Överföring över nätverket av information som identifierar personen som ringer samtalet.

I vissa RPC-implementeringar (.NET Remoting) är delsystemsgränser öppna polymorfa gränssnitt, och det är möjligt att skriva en egen implementering av nästan alla delsystem som listas. I andra implementeringar (DCE RPC på Windows) är detta inte fallet.

se även

Remote Procedure Call (RPC) Remote Procedure Call Concept

Tanken bakom Remote Procedure Call (RPC) är att utöka den välkända och välkända mekanismen för att överföra kontroll och data inom ett program som körs på en enda maskin för att överföra kontroll och data över ett nätverk. Fjärrproceduranropsfaciliteter är utformade för att underlätta organisationen av distribuerad datoranvändning. Den mest effektiva användningen av RPC uppnås i de applikationer där det finns interaktiv kommunikation mellan fjärrkomponenter med korta svarstider och relativt lite dataöverföring. Sådana applikationer kallas RPC-orienterade.

Lokala procedursamtal kännetecknas av:

  • Asymmetri, det vill säga en av de interagerande parterna är initiativtagaren;
  • Synkronicitet, det vill säga exekveringen av anropsproceduren avbryts från det ögonblick då begäran utfärdas och återupptas först efter att ha återvänt från den anropade proceduren.

Att implementera fjärranrop är betydligt mer komplext än att implementera lokala procedursamtal. Till att börja med, eftersom uppringaren och uppringaren exekveras på olika maskiner, har de olika adressutrymmen, och detta skapar problem vid överföring av parametrar och resultat, speciellt om maskinerna inte är identiska. Eftersom RPC inte kan räkna med delat minne betyder det att RPC-parametrar inte får innehålla pekare till icke-stackminnesplatser och att parametervärden måste kopieras från en dator till en annan. Nästa skillnad mellan RPC och ett lokalsamtal är att det nödvändigtvis använder det underliggande kommunikationssystemet, men detta bör inte uttryckligen ses vare sig i definitionen av procedurer eller i själva procedurerna. Avstånd inför ytterligare problem. Exekveringen av det anropande programmet och den anropade lokala proceduren på samma maskin görs i en enda process. Men det finns minst två processer involverade i RPC-implementering - en på varje maskin. Om en av dem avslutas onormalt kan följande situationer uppstå: om anropsproceduren kraschar, kommer de fjärranropade procedurerna att bli "föräldralösa", och om fjärrprocedurerna avslutas onormalt, kommer de som ringer att bli "berövade föräldrar" av anropsprocedurerna, som förgäves väntar på svar från fjärrprocedurerna.

Dessutom finns det ett antal problem förknippade med heterogeniteten hos programmeringsspråk och operativa miljöer: datastrukturer och proceduranropsstrukturer som stöds i ett programmeringsspråk stöds inte på samma sätt på alla andra språk.

Dessa och några andra problem löses av den utbredda RPC-tekniken som ligger till grund för många distribuerade operativsystem. Grundläggande RPC-operationer

För att förstå hur RPC fungerar, överväg att först utföra ett lokalt proceduranrop på en konventionell maskin som körs autonomt. Låt det till exempel vara ett systemanrop

count = read (fd, buf, nbytes);

där fd är ett heltal, buf är en teckenuppsättning och nbytes är ett heltal.

För att ringa anropet trycker anropsproceduren parametrarna till stacken i omvänd ordning (Figur 3.1). Efter att anropet att läsa har utförts, placerar den returvärdet i ett register, flyttar fram returadressen och återgår kontrollen till anropsproceduren, som poppar upp parametrarna från stacken och återställer den till sitt ursprungliga tillstånd. Observera att i C kan parametrar anropas antingen genom referens (med namn) eller genom värde (efter värde). Med avseende på den anropade proceduren är värdeparametrar initierbara lokala variabler. Den anropade proceduren kan ändra dem utan att påverka värdet på originalen av dessa variabler i anropsproceduren.

Om en pekare till en variabel skickas till den anropade proceduren, ändras värdet på denna variabel med den anropade proceduren också för att ändra värdet på denna variabel för anropsproceduren. Detta faktum är viktigt för RPC.

Det finns också en annan mekanism för att skicka parametrar, som inte används i språket C. Den kallas call-by-copy / restore och består i att det anropande programmet måste kopiera variabler till stacken som värden, och sedan kopiera tillbaka dem efter samtalet görs över de ursprungliga värdena för anropsproceduren.

Det är upp till språkdesignerna att bestämma vilken parameteröverföringsmekanism som ska användas. Ibland beror det på vilken typ av data som överförs. I C, till exempel, skickas heltal och andra skalära data alltid med värde, och matriser skickas alltid med referens.

Ansökan

Många av Windows-operativsystemets fjärrhanteringsverktyg (Event Viewer, Server Manager, Print Management, User Lists) använder DCE RPC som ett sätt för nätverkskommunikation mellan den hanterade tjänsten och den hanterande användargränssnittsapplikationen. DCE RPC-stöd har funnits i Windows NT sedan den allra första versionen 3.1. DCE RPC-klienter stöddes också på den lätta linjen i operativsystemet Windows 3.x / 95/98 / Me.

Windows-systembiblioteken som tillhandahåller sådan kontroll och fungerar som baslager för kontrollanvändargränssnittstillämpningar (netapi32.dll och delvis advapi32.dll) innehåller faktiskt klientkoden för DCE RPC-gränssnitten som utför denna kontroll.

Denna arkitektoniska design har varit föremål för intensiv kritik från Microsoft. De generiska rangeringsprocedurerna som finns i DCE RPC är mycket komplexa och har en enorm potential för brister som kan utnyttjas i nätverket genom att skicka ett avsiktligt missformat DCE RPC-paket. En betydande del av Windows-säkerhetsbristerna som upptäcktes från slutet av 1990-talet till mitten av 2000-talet var buggar i DCE RPC-rangeringskoden.

Förutom DCE RPC använder Windows aktivt DCOM-teknik. Den används till exempel som ett kommunikationsmedel mellan IIS webbserverhanteringsverktyg och den hanterade servern själv. Ett fullt fungerande gränssnitt för att kommunicera med MS Exchange Server-postsystemet - MAPI - är också baserat på DCOM.



Program som kommunicerar över ett nätverk behöver en kommunikationsmekanism. På den lägre nivån, vid mottagande av paket, behandlas en signal av nätverkssignalbehandlingsprogrammet. På toppnivån fungerar rendezvous-mekanismen, antagen på Ada-språket. NFS använder en RPC-mekanism (Remote Procedure Call) där klienten kommunicerar med servern (se figur 1). I enlighet med denna process kommer klienten först åt en procedur som skickar en begäran till servern. Vid ankomsten av ett paket med en begäran anropar servern proceduren för dess öppning, utför den begärda tjänsten, skickar ett svar och kontrollen returneras till klienten.

RPC-gränssnittet kan tänkas ha tre lager:

  1. Den övre nivån är helt genomskinlig. Ett program på denna nivå kan till exempel anropa rnusers (), vilket returnerar antalet användare på fjärrmaskinen. Du behöver inte veta om att använda RPC-mekanismen eftersom du ringer i programmet.
  2. Mellanskiktet är för de vanligaste applikationerna. RPC-anrop på denna nivå hanteras av rutinerna registerrpc () och callrpc (): registerrpc () tar emot systemomfattande mörk kod, och callrpc () utför ett fjärrproceduranrop. Anropet rnusers () implementeras med dessa två rutiner.
  3. Den lägre nivån används för mer komplexa uppgifter, vilket ändrar standarden till värdena för procedurparametrar. På den här nivån kan du explicit manipulera uttagen som används för att överföra RPC-meddelanden.

Som en allmän regel bör du använda det övre lagret och undvika att använda de undre lagren i onödan.

Trots det faktum att vi i denna handledning endast betraktar gränssnittet i C, kan anrop till fjärrprocedurer göras från vilket språk som helst. RPC-mekanismens arbete för att organisera kommunikation mellan processer på olika maskiner skiljer sig inte från dess arbete på samma maskin.

RPC (Remote Procedure Call) är ett gränssnitt mellan fjärranvändare och specifika värdprogram som anropas av dessa användare. En RPC-tjänst för en värd tillhandahåller vanligtvis en uppsättning program till klienter. Vart och ett av dessa program består i sin tur av en eller flera fjärrprocedurer. Till exempel kan en fjärrfilsystemtjänst för NFS som är beroende av RPC-anrop bara bestå av två program: till exempel interagerar ett program med användargränssnitt på hög nivå och det andra med I/O-funktioner på låg nivå.

Varje RPC-anrop involverar två parter: den aktiva klienten, som skickar proceduranropsbegäran till servern, och servern, som skickar svaret till klienten.

Notera. Observera att termerna "klient" och "server" i detta fall hänvisar till en specifik transaktion. En specifik värd eller mjukvara (process eller program) kan fungera som antingen en klient eller en server. Till exempel kan ett program som tillhandahåller driften av fjärrprocedurtjänsten samtidigt vara en klient i arbetet med nätverksfilsystemet.

RPC bygger på en fjärranropsmodell som liknar den för lokala proceduranrop. När du anropar en lokal procedur skickar du argument till en specifik minnesplats, stack eller miljövariabler och överför kontrollen över processen till en specifik adress. Efter avslutat arbete läser du resultatet på en specifik adress och fortsätter din process.

När det gäller en fjärrprocedur är den största skillnaden att fjärrfunktionsanropet betjänas av två processer: klientprocessen och serverprocessen.

Klientprocessen skickar ett meddelande till servern, som inkluderar parametrarna för den anropade proceduren och väntar på ett svarsmeddelande med resultatet av dess arbete. När ett svar tas emot läses resultatet och processen fortsätter. På serversidan är samtalshanterarprocessen i vänteläge, och när ett meddelande kommer, läser den procedurens parametrar, exekverar den, skickar ett svar och hamnar i vänteläge för nästa samtal.

RPC-protokollet ställer inga krav på ytterligare kommunikationer mellan processer och kräver inte synkronisering av de utförda funktionerna, det vill säga samtal kan vara asynkrona och icke-oberoende, så att klienten kan utföra andra procedurer i väntan på ett svar. RPC-servern kan tilldela en separat process eller virtuell maskin för varje funktion, därför kan den, utan att vänta på att de tidigare förfrågningarna ska avslutas, omedelbart acceptera nästa.

Det finns dock flera viktiga skillnader mellan lokala och fjärranrop:

  1. Fel vid bearbetning. Klienten ska i alla fall meddelas om fel som uppstår vid anrop av fjärrprocedurer på servern eller på nätverket.
  2. Globala variabler. Eftersom servern inte har tillgång till klientens adressutrymme kan du inte använda dolda parametrar i form av globala variabler i fjärranrop.
  3. Prestanda. Exekveringshastigheten för fjärrprocedurer är som regel en eller två storleksordningar lägre än exekveringshastigheten för liknande lokala procedurer.
  4. Autentisering. Eftersom fjärranrop sker över nätverket måste klientautentiseringsmekanismer användas.

Principer för att konstruera protokollet.

RPC-protokollet kan använda flera olika transportprotokoll. RPC-protokollets enda ansvar är att upprätthålla standarder och tolka meddelandeöverföring. Tillförlitligheten och tillförlitligheten för meddelandeöverföring säkerställs helt och hållet av transportskiktet.

RPC kan dock styra valet och vissa funktioner i transportprotokollet. Som ett exempel på interaktionen mellan RPC och transportprotokollet, överväg proceduren för att tilldela en RPC-port för en applikationsprocess via RPC - Portmapper.

Denna funktion tilldelar dynamiskt (på begäran) en specifik port till en RPC-anslutning. Portmapper-funktionen används ofta eftersom uppsättningen av transportportar reserverade för RPC är begränsad och antalet processer som potentiellt kan köras samtidigt är mycket högt. Portmapper, till exempel, anropas när du väljer kommunikationsportar för en NFS-systemklient och -server.

Portmapper-tjänsten använder RPC broadcast-meddelandemekanismen till en specifik port - III. På den här porten sänder klienten en begäran om porten för en specifik RPC-tjänst. Portmapper-tjänsten behandlar skattemeddelandet, bestämmer adressen till den lokala RPC-tjänsten och skickar ett svar till klienten. RPC Portmapper-tjänsten kan fungera med både TCP- och UDP-protokoll.

RPC kan fungera med olika transportprotokoll, men det duplicerar aldrig deras funktioner, det vill säga om RPC körs ovanpå TCP lämnar RPC alla bekymmer om tillförlitligheten och tillförlitligheten av kopplingen till TCP. Men om RPC är installerat ovanpå UDP kan det ge ytterligare inbyggd funktionalitet för att säkerställa att meddelandeleverans är garanterad.

Notera.

Applikationer kan se RPC-protokollet som en definierad funktionsanropsprocedur över ett JSR-nätverk (Jump Subroutine Instruction).

För att RPC-protokollet ska fungera måste följande villkor vara uppfyllda:

  1. Unik identifiering av alla fjärranropade procedurer på en given värd. RPC-begäranden innehåller tre fält med identifierare - numret på fjärrprogrammet (tjänsten), versionsnumret för fjärrprogrammet och numret på fjärrproceduren för det angivna programmet. Programnumret tilldelas av tillverkaren av tjänsten, procedurnumret indikerar den specifika funktionen för denna tjänst
  2. Identifiering av RPC-protokollets version. RPC-meddelanden innehåller ett RPC-protokollversionsfält. Den används för att matcha formaten för de överförda parametrarna när klienten arbetar med olika versioner av RPC.
  3. Tillhandahåller mekanismer för autentisering av klienten till servern. RPC-protokollet tillhandahåller en procedur för att autentisera klienten i tjänsten, och, om nödvändigt, med varje begäran eller skicka ett svar till klienten. Dessutom tillåter RPC olika ytterligare säkerhetsmekanismer att användas.

RPC kan använda fyra typer av autentiseringsmekanismer:

  • AUTH_NULL - ingen autentisering krävs
  • AUTH_UNIX - UNIX standardautentisering
  • AUTH_SHORT - UNIX standardautentisering med sin egen kodningsstruktur
  • AUTH_DES - DES-autentisering
  1. Identifiering av svarsmeddelanden på motsvarande förfrågningar. RPC-svarsmeddelanden innehåller ID:t för begäran de baserades på. Denna identifierare kan kallas transaktionsidentifieraren för RPC-anropet. Denna mekanism är särskilt användbar när du arbetar i asynkront läge och när du kör en sekvens av flera RPC-anrop.
  2. Identifiering av protokollfel. Alla nätverks- eller serverfel har unika identifierare med vilka var och en av deltagarna i anslutningen kan fastställa orsaken till felet.

Protokollmeddelandestrukturer

Vid överföring av RPC-meddelanden över ett transportprotokoll kan flera RPC-meddelanden finnas inom ett transportpaket. För att särskilja ett meddelande från ett annat används en postmarkör (RM - Record Marker). Varje RPC-meddelande är "märkt" med exakt en RM.

Ett RPC-meddelande kan bestå av flera fragment. Varje bit består av fyra byte med rubrik och (0 till 2 ** 31-1) data. Den första biten i rubriken indikerar om biten är den sista, och de återstående 31 bitarna indikerar längden på datapaketet.

RPC:s struktur beskrivs formellt på språket för beskrivning och representation av dataformat - XDR med tillägg angående beskrivning av procedurer. Man kan till och med säga att RPC-markeringsspråket är en förlängning av XDR, kompletterat med arbete med procedurer.

Strukturen för RPC-paketet ser ut så här:


Strukturen reply_body kan innehålla antingen en struktur som skickas vidare i händelse av ett fel (i vilket fall den innehåller felkoden), eller en struktur för framgångsrik bearbetning av begäran (i vilket fall den innehåller de returnerade data).

Programmeringsgränssnitt på hög nivå.

Att använda subrutiner i ett program är det traditionella sättet att strukturera en uppgift, för att göra den tydligare. De mest använda subrutinerna finns samlade i bibliotek, där de kan användas av olika program. I det här fallet talar vi om ett lokalt (lokalt) samtal, det vill säga både den som ringer och de anropade objekten fungerar inom samma program på samma dator.

I fallet med en fjärranrop startar en process som körs på en dator processen på fjärrdatorn (det vill säga den kör faktiskt procedurkoden på fjärrdatorn). Uppenbarligen skiljer sig ett fjärrproceduranrop avsevärt från ett traditionellt lokalt, men från en programmerares synvinkel finns det praktiskt taget inga sådana skillnader, det vill säga arkitekturen för ett fjärrproceduranrop låter dig simulera ett lokalt samtal.

Men om, i fallet med ett lokalt samtal, programmet skickar parametrar till den anropade proceduren och tar emot resultatet av arbetet genom stacken eller delade minnesområdena, förvandlas i fallet med ett fjärranrop överföringen av parametrar till en överföring av en förfrågan över nätverket, och resultatet av arbetet finns i det mottagna svaret.

Detta tillvägagångssätt är en möjlig grund för att skapa distribuerade applikationer, och även om många moderna system inte använder denna mekanism, finns de grundläggande begreppen och termerna i många fall kvar. När vi beskriver RPC-mekanismen kommer vi traditionellt att referera till anropsprocessen som klienten och fjärrprocessen som implementerar proceduren som servern.

Ett fjärranrop innehåller följande steg:

  1. Klientprogrammet gör ett lokalt anrop till en procedur som kallas stubb. Samtidigt "verkar" klienten att genom att anropa stubben, gör den faktiskt ett anrop till serverproceduren. Faktum är att klienten skickar de nödvändiga parametrarna till stubben och den returnerar resultatet. Det är dock inte exakt så som klienten föreställer sig det. Stubbens uppgift är att acceptera argument för fjärrproceduren, eventuellt konvertera dem till något standardformat och bilda en nätverksbegäran. Att packa argument och göra en nätverksbegäran kallas för rangering.
  2. Nätverksbegäran skickas över nätverket till fjärrsystemet. För att göra detta använder stubben lämpliga anrop, till exempel de som diskuterades i föregående avsnitt. Observera att i detta fall kan olika transportprotokoll användas, och inte bara av TCP/IP-familjen.
  3. På fjärrvärden sker allt i omvänd ordning. Serverstubben väntar på begäran och, vid mottagandet, hämtar parametrarna — argumenten för proceduranropet. Extrahering (unmarshalling) kan innebära nödvändiga omvandlingar (till exempel ändra ordningen på bytes).
  4. Stubben gör ett anrop till den verkliga serverprocedur som klientens begäran riktas till och skickar de mottagna argumenten över nätverket.
  5. Efter att ha slutfört proceduren återgår kontrollen till serverstubben och skickar de nödvändiga parametrarna till den. Som en klientstubb; serverstubben konverterar värdena som returneras av proceduren för att bilda ett nätverkssvarsmeddelande som skickas över nätverket till systemet från vilket förfrågan kom.
  6. Operativsystemet skickar det mottagna meddelandet till klientstubben, som efter den nödvändiga transformationen skickar värdena (som är de värden som returneras av fjärrproceduren) till klienten, som tolkar detta som en normal retur från procedur.

Sålunda, från klientens synvinkel, gör den ett fjärranrop som det skulle göra för ett lokalt. Detsamma kan sägas om servern: proceduren anropas på vanligt sätt, ett objekt (serverstubb) anropar den lokala proceduren och tar emot värdena som returneras av den. Klienten behandlar stubben som en anropsbar serverprocedur och servern tolkar sin egen stubb som klienten.

Således utgör stubbar kärnan i RPC-systemet, ansvarig för alla aspekter av generering och överföring av meddelanden mellan klienten och fjärrservern (procedur), även om både klienten och servern antar att samtalen görs lokalt. Detta är grundkonceptet för RPC - att helt dölja den distribuerade (nätverks)naturen för kommunikation i stubbkoden. Fördelarna med detta tillvägagångssätt är uppenbara: både klienten och servern är oberoende av nätverksimplementeringen, de arbetar båda inom en distribuerad virtuell maskin och proceduranrop har ett standardgränssnitt.

Passerar parametrar

Att skicka värdeparametrar är enkelt. I det här fallet placerar klientstubben parametervärdet i nätverksbegäran, och utför eventuellt konverteringar till standardformuläret (till exempel ändra byteordningen). Situationen med att passera pekare är mycket mer komplicerad, när parametern är adressen till datan och inte deras värde. Att skicka en adress i en begäran är meningslöst, eftersom fjärrproceduren exekveras i ett helt annat adressutrymme. Den enklaste RPC-lösningen är att förhindra klienter från att skicka parametrar på annat sätt än efter värde, även om detta verkligen medför allvarliga begränsningar.

Bindande

Innan en klient kan anropa en fjärrprocedur måste den binda till fjärrsystemet som är värd för den nödvändiga servern. Därför är uppgiften att länka uppdelad i två:

  1. Hitta fjärrvärden med den önskade servern
  2. Att hitta den nödvändiga serverprocessen på en given värd

Olika metoder kan användas för att hitta en värd. Ett möjligt alternativ är att skapa någon form av centraliserad katalog där värdar tillkännager sina servrar, och där klienten, om så önskas, kan välja den värd- och proceduradress som passar honom.

Varje RPC-procedur identifieras unikt av ett program- och procedurnummer. Programnumret definierar en grupp av fjärrprocedurer, som var och en har sitt eget nummer. Varje program tilldelas också ett versionsnummer, så att när mindre ändringar görs i programmet (till exempel när en procedur läggs till) finns det inget behov av att ändra dess nummer. Vanligtvis implementeras flera funktionellt likartade procedurer i en programmodul, som, när den startas, blir servern för dessa procedurer, och som identifieras av programnumret.

Sålunda, när en klient vill anropa en fjärrprocedur, måste han känna till programmet, versionen och procedurnumren som tillhandahåller den erforderliga tjänsten.

För att skicka begäran måste klienten också känna till värdens nätverksadress och portnummer som är associerat med serverprogrammet som tillhandahåller de nödvändiga procedurerna. Detta görs med hjälp av portmap (IM) daemon (kallas rpcbind (IM) på vissa system). Demonen körs på en värd som tillhandahåller fjärrprocedurtjänster och använder ett välkänt portnummer. När en serverprocess initieras registrerar den sina rutiner och portnummer med portmap (IM). Nu, när klienten behöver veta portnumret för att anropa en viss procedur, skickar den en begäran till portmap-servern (IM), som i sin tur antingen returnerar portnumret eller omdirigerar begäran direkt till RPC-servern och returnerar en svar till klienten när det utförs. I alla fall, om den nödvändiga proceduren finns, får klienten procedurens portnummer från portmap-servern (IM), och ytterligare förfrågningar kan göras direkt till denna port.

Hantera undantag

Att hantera undantag när man ringer till lokala rutiner är inte särskilt problematiskt. UNIX hanterar processfel som division med noll, ogiltiga minnesåtkomster etc. Att anropa en fjärrprocedur ökar sannolikheten för felsituationer. Till server- och stubbfel läggs fel relaterade till att till exempel ta emot ett felaktigt nätverksmeddelande.

Till exempel, när du använder UDP som transportprotokoll, sänds meddelanden om efter en specificerad timeout. Ett fel returneras till klienten om ett svar från servern inte har mottagits efter ett visst antal försök. I det fall där TCP-protokollet används, returneras ett fel till klienten om servern avslutade TCP-anslutningen.

Ring semantik

Att anropa en lokal procedur leder otvetydigt till dess exekvering, varefter kontrollen återgår till huvudprogrammet. Situationen är annorlunda när man anropar en fjärrprocedur. Det är omöjligt att fastställa exakt när proceduren kommer att utföras, om den kommer att utföras överhuvudtaget, och i så fall hur många gånger? Till exempel, om begäran tas emot av fjärrsystemet efter att serverprogrammet avslutats på ett onormalt sätt, kommer proceduren inte att exekveras alls. Om klienten, efter att inte ha fått något svar efter en viss tidsperiod (timeout), skickar begäran på nytt, kan en situation uppstå när svaret redan överförs över nätverket och den upprepade begäran återigen accepteras för behandling av fjärrprocedur. I det här fallet kommer proceduren att utföras flera gånger.

Sålunda kan exekveringen av en fjärrprocedur karakteriseras av följande semantik:

  • En och bara en gång. Detta beteende (i vissa fall det mest önskvärda) är svårt att upprätthålla på grund av potentiella serverkrascher.
  • Maxtider. Detta innebär att proceduren antingen inte utfördes alls eller endast utfördes en gång. Ett liknande uttalande kan göras när ett fel tas emot istället för ett normalt svar.
  • Åtminstone en gång. Ingreppet utfördes troligen en gång, men möjligen fler. För normal drift i en sådan situation måste fjärrproceduren ha egenskapen idempotens (från den engelska idemponenten). Denna egenskap innehas av en procedur, vars upprepade exekvering inte orsakar kumulativa förändringar. Till exempel är det idempotent att läsa en fil, men att lägga till text i en fil är det inte.

Datapresentation

När klienten och servern körs på samma system på samma dator finns det inga datainkompatibilitetsproblem. Den binära datan representeras på samma sätt för både klienten och servern. I fallet med ett fjärranrop kompliceras saken av att klienten och servern kan köras på system med olika arkitekturer med olika datarepresentationer (till exempel flyttalsvärdesrepresentation, byteordning, etc.)

De flesta RPC-implementationer definierar någon standardrepresentation av data till vilken alla värden som skickas i förfrågningar och svar måste konverteras.

Till exempel är formatet för att representera data i RPC från Sun Microsystems följande:

  1. Byteordning - Mest betydande - Sist
  2. Floating Point Representation - IEEE
  3. Karaktärsrepresentation - ASCII

Nätverk

När det gäller funktionalitet ligger RPC-systemet mellan applikationslagret och transportskiktet. Enligt OSI-modellen motsvarar denna bestämmelse presentations- och sessionslagren. RPC är således teoretiskt oberoende av nätverksimplementeringen, i synnerhet från transportskiktets nätverksprotokoll.

Programvaruimplementationer av systemet stöder som regel ett eller två protokoll. Till exempel stöder Sun Microsystems RPC-system meddelandehantering med TCP- och UDP-protokollen. Valet av ett eller annat protokoll beror på applikationens krav. Valet av UDP är motiverat för applikationer med följande egenskaper:

  • Kallade procedurer är idempotenta
  • Storleken på argumenten som skickas och det returnerade resultatet är mindre än storleken på UDP-paketet - 8 KB.
  • Servern ger arbete med flera hundra klienter. Eftersom servern, när man arbetar med TCP-protokoll, tvingas upprätthålla en anslutning till var och en av de aktiva klienterna, tar detta upp en betydande del av dess resurser. UDP är mindre resurskrävande i detta avseende.

Å andra sidan ger TCP effektiv drift av applikationer med följande egenskaper:

  • Applikationen kräver tillförlitligt överföringsprotokoll
  • Kallade procedurer är inte identiska
  • Argument eller returnerade resultat är större än 8KB

Valet av protokoll förblir vanligtvis hos klienten, och systemet organiserar bildandet och överföringen av meddelanden på olika sätt. Så när du använder TCP-protokollet, för vilket de överförda data är en ström av byte, är det nödvändigt att separera meddelandena från varandra. Detta kan t.ex. göras med RFC1057 "RPC: Remote Procedure Call Protocol specification version 2" record labeling protocol, som föregår varje meddelande med ett 32-bitars heltal som anger meddelandestorleken i byte.

Situationen är annorlunda med samtalets semantik. Till exempel, om RPC utförs med hjälp av ett opålitligt transportprotokoll (UDP), återsänder systemet meddelandet med korta intervall (timeouts). Om klientapplikationen inte får något svar, är det säkert att säga att proceduren har utförts noll eller fler gånger. Om svar har inkommit kan ansökan dra slutsatsen att förfarandet har verkställts minst en gång. Med tillförlitligt transportprotokoll (TCP), när ett svar tas emot, kan proceduren sägas ha utförts en gång. Om inget svar erhålls är det omöjligt att med säkerhet säga att proceduren inte utfördes3.

Hur det fungerar?

I huvudsak är det faktiska RPC-systemet inbyggt i klientprogrammet och serverprogrammet. Det är glädjande att när du utvecklar distribuerade applikationer behöver du inte fördjupa dig i detaljerna i RPC-protokollet eller programmeddelandebehandling. Systemet förutsätter att det finns en lämplig utvecklingsmiljö, vilket i hög grad underlättar livet för skaparna av applikationsprogramvara. En av nyckelpunkterna i RPC är att utvecklingen av en distribuerad applikation börjar med definitionen av ett objektgränssnitt - en formell beskrivning av serverfunktioner, skriven på ett speciellt språk. Klient- och serverstubbar genereras sedan automatiskt från detta gränssnitt. Det enda som behöver göras efter detta är att skriva själva procedurkoden.

Som ett exempel, betrakta RPC från Sun Microsystems. Systemet består av tre huvuddelar:

  • rpcgen (1) är en RPC-kompilator som genererar klient- och serverstubbar som C-program baserat på beskrivningen av fjärrprocedurens gränssnitt.
  • Library XDR (eXternal Data Representation), som innehåller funktioner för att konvertera olika typer av data till en maskinoberoende form, vilket möjliggör utbyte av information mellan heterogena system.
  • Ett bibliotek med moduler som säkerställer driften av systemet som helhet.

Låt oss titta på ett exempel på en grundläggande distribuerad händelseloggningsapplikation. Klienten, vid uppstart, anropar fjärrproceduren för att skriva ett meddelande till loggfilen på fjärrdatorn.

För att göra detta måste du skapa minst tre filer: specifikationen av gränssnitten för log.x-fjärrprocedurerna (i gränssnittsbeskrivningsspråket), den faktiska texten för log.c-fjärrprocedurerna och texten för klientens huvudprogram main () - client.c (på C-språket).

rpcgen (l)-kompilatorn genererar tre filer baserat på log.x-specifikationen: C-klienten och serverns stubbtext (log clnt.c och log svc.c) och log.h-definitionsfilen som används av båda stubbarna.

Så låt oss titta på källkoden för programmen.

Den här filen specificerar registreringsparametrarna för fjärrproceduren — program-, versions- och procedurnummer — och definierar anropsgränssnittet — inmatningsargument och returvärden. Således är RLOG-proceduren definierad, som tar en sträng som ett argument (som kommer att skrivas till loggen), och returvärdet indikerar som standard framgång eller misslyckande för den beställda operationen.


program LOG_PROG ( version LOG_VER ( int RLOG (sträng) = 1; ) = 1; ) = 0x31234567;

rpcgen (l)-kompilatorn genererar en rubrikfil log.h där i synnerhet procedurerna är definierade:


Låt oss ta en närmare titt på den här filen. Kompilatorn översätter RLOG-namnet som anges i gränssnittsbeskrivningen till rlog_1, ersätter versaler med gemener och lägger till programversionsnumret med ett understreck. Returtypen har ändrats från int till int *. Detta är regeln - RPC låter dig skicka och ta emot endast adresserna till parametrarna som deklareras när du beskriver gränssnittet. Samma regel gäller för strängen som skickas som ett argument. Även om detta inte följer av print.h-filen, skickas faktiskt även adressen till raden som ett argument till funktionen rlog_l ().

Förutom header-filen genererar rpcgen (l)-kompilatorn klientstub- och serverstubmoduler. I huvudsak innehåller texten i dessa filer all kod för fjärrsamtalet.

Serverstubben är huvudprogrammet som hanterar all nätverksinteraktion med klienten (mer exakt med dess stubb). För att utföra operationen ringer serverstubben ett lokalt anrop till funktionen, vars text måste skrivas:


Klientstubben tar ett argument som skickas till fjärrproceduren, gör nödvändiga transformationer, skickar en begäran till portmap-servern (1M), kommunicerar med fjärrprocedurservern och skickar slutligen returvärdet till klienten. För klienten är ett fjärranrop ett anrop och skiljer sig inte från ett vanligt lokalsamtal.

klient.c


#omfatta #omfatta"log.h" huvud(int argc, röding* argv) (KLIENT * cl; röding* server, * mystring, * clnttime; time_t bintime; int* resultat; om(argc! = 2) (fprintf (stderr, "Samtalsformat:% s Värdadress \ n", argv); avsluta (1);) server = argv; / * Hämta klientbeskrivningen. I händelse av fel kommer vi att informera dig om omöjligheten att upprätta en anslutning till servern * / om((c1 = clnt_create (server, LOG_PROG, LOG_VER, "udp")) == NULL) (clnt_pcreateerror (server); exit (2);) / * Tilldela en buffert för strängen * / mystring = ( röding*) mallok (100); / * Bestäm tidpunkten för händelsen * / bintime = tid ((tid_t *) NULL); clnttime = ctime (& bintime); sprintf (mystring, "% s - Klient startad", clnttime); / * Låt oss skicka ett meddelande för loggen - den tidpunkt då klienten började arbeta. I händelse av fel kommer vi att rapportera ett fel * / om((resultat = rlog_l (& mystring, cl)) == NULL) (fprintf (stderr, "error2 \ n"); clnt_perror (cl, server); avsluta (3);) / * Vid fel på fjärrdatorn kommer vi att rapportera ett fel * / om(* resultat! = 0) fprintf (stderr, "Fel vid skrivning till logg \ n"); / * 0 frigör deskriptorn * / cint förstöra (cl); utgång (0); )

Klientstubben log_clnt.c kompileras med client.c-modulen för att få klienten körbar.


Nu på någon värd server.nowhere.ru är det nödvändigt att starta serverprocessen:


$ logger

Sedan, när rlog-klienten startas på en annan dator, kommer servern att lägga till en motsvarande post i loggfilen.

Schemat för RPC-drift i detta fall visas i fig. 1. Moduler interagerar enligt följande:

  1. När serverprocessen startar skapar den en UDP-socket och binder alla lokala portar till den socket. Servern anropar sedan biblioteksfunktionen svc_register (3N) för att registrera programnummer och versionsnummer. För att göra detta anropar funktionen portmap-processen (IM) och skickar de nödvändiga värdena. Portmap-servern (IM) startas vanligtvis under systeminitiering och binder till någon välkänd port. Portmap (3N) känner nu till portnumret för vårt program och version. Servern väntar på att ta emot begäran. Observera att alla beskrivna åtgärder utförs av en serverstubb som genereras av rpcgen (IM) kompilatorn.
  2. När rlog startar är det första den gör att anropa biblioteksfunktionen clnt_create (3N) och ge den adressen till fjärrsystemet, program- och versionsnumren och transportprotokollet. Funktionen gör en begäran till portmap-servern (IM) för fjärrsystemet server.nowhere.m och erhåller fjärrportnumret för loggservern.
  3. Klienten anropar rutinen rlog_1 () definierad i klientstubben och överför kontrollen till stubben. Det i sin tur bildar begäran (som konverterar argumenten till XDR-format) i form av ett UDP-paket och vidarebefordrar det till fjärrporten som tas emot från portmap-servern (IM). Sedan väntar den på svar ett tag och, om den inte mottas, skickar den om begäran. Under gynnsamma omständigheter accepteras begäran av loggerservern (serverstubmodul). Stubben bestämmer vilken funktion som anropades (av procedurnumret) och anropar funktionen rlog_1 () för log.c-modulen. Efter att kontroll återgår till stubben, konverterar stubben värdet som returneras av funktionen rlog_1 () till XDR-format och bildar svaret även i form av ett UDP-paket. Efter att ha mottagit svaret extraherar klientstubben det returnerade värdet, konverterar det och returnerar det till klientvärden

En mycket viktig mekanism för klient-serverapplikationer tillhandahålls av RPC ( Fjärrproceduranrop). RPC utvecklades av Sun Micrsystems och är en samling verktyg och biblioteksfunktioner. I synnerhet fungerar NIS (Network Information System) och NFS (Network File System) på RPC.

RPC-servern består av ett system med sådana procedurer som klienten kan komma åt genom att skicka en RPC-begäran till servern tillsammans med parametrarna för proceduren. Servern anropar den angivna proceduren och returnerar returvärdet för proceduren, om någon. För att vara maskinoberoende konverteras all data som utbyts mellan klienten och servern till en så kallad extern datarepresentation ( Extern datarepresentation, XDR). RPC är associerat med UDP- och TCP-uttag för överföring av data i XDR-format. Sun har förklarat RPC som en allmän egendom, och dess beskrivning finns tillgänglig i en serie RFC:er.

Ibland introducerar ändringar i RPC-applikationer inkompatibiliteter i anropsproceduren för ett gränssnitt. Naturligtvis, med en enkel ändring, skulle servern förstöra alla applikationer som fortfarande väntar på de gamla samtalen. Därför har RPC-program versionsnummer tilldelade, vanligtvis med 1. Varje ny RPC-version håller reda på versionsnumret. Ofta kan en server erbjuda flera versioner samtidigt. Kunder i detta fall anger det versionsnummer de vill använda.

Nätverket mellan RPC-servrar och klienter är lite speciellt. RPC-servern erbjuder en eller flera systemrutiner, varje uppsättning av sådana rutiner kallas ett program ( program) och identifieras unikt av programnumret ( programnummer). Listan över tjänstnamn lagras vanligtvis i / etc / rpc, ett exempel på det visas nedan.

Exempel 12-4. Exempel / etc / rpc-fil

# # / Etc / RPC - diverse RPC-baserade tjänster # portmappern 100000 portmap sunrpc rstatd 100001 rstat rstat_svc rup perfmeter rusersd 100.002 rusers NFS 100003 nfsprog ypserv 100004 ypprog mountd 100005 montera showmount yparabind 100007 yparabind 100007 walldassated 1000wdwallass shutdown9 yppppate

I TCP/IP-nätverk fick författarna till RPC i uppdrag att kartlägga programnummer till delade nätverkstjänster. Varje server tillhandahåller en TCP- och UDP-port för varje program och varje version. I allmänhet använder RPC-applikationer UDP för att överföra data och faller tillbaka till TCP när data som ska överföras inte passar in i ett enda UDP-datagram.

Givetvis måste klientprogram ha ett sätt att ta reda på vilken port som motsvarar programnumret. Att använda en konfigurationsfil för detta skulle vara för oflexibelt; eftersom RPC-applikationer inte använder reserverade portar, finns det ingen garanti för att porten inte är upptagen av någon applikation och är tillgänglig för oss. Därför väljer RPC-applikationer vilken port de kan få och registrerar detta med portmapper demon... En klient som vill kontakta en tjänst med ett givet programnummer kommer först att göra en förfrågan till portmappern för att ta reda på portnumret för den önskade tjänsten.

Denna metod har nackdelen att den introducerar en enda felpunkt som är mycket lik inetd demon. Det här fallet är dock lite värre, för när portmappern kraschar går all RPC-portinformation förlorad. Detta innebär vanligtvis att du måste starta om alla RPC-servrar manuellt eller starta om maskinen.

På Linux heter portmappern / sbin / portmap eller /usr/sbin/rpc.portmap. Bortsett från att startas från ett nätverksstartskript kräver portmapper inget konfigurationsarbete.

Efter att ha startat om datorn startade inte tjänsten " Remote Procedure Call (RPC)". Mycket beror på den här tjänsten. Som ett resultat fungerar inte Systemåterställning, Nätverkskvarter, Ljud, Windows Installer, Management Console (MMC) fungerar nästan inte, öppna fönster visas inte i aktivitetsfältet, etc., etc. Ett försök att starta manuellt resulterar i ett fel " Det gick inte att starta ... (RPC) på xxxComp. Fel 5: Åtkomst nekad". Antiviruset hittade inget. Två dagars grävande och datorn väcktes till liv igen.

Som rekommenderat av Microsoft var det första jag försökte hitta och ta bort registernyckeln ... Jag hade det inte, möjligen som ett resultat av några installerade uppdateringar.

Därefter görs ett försök att återställa tjänstens parametrar i registret. Eftersom regedit.exe bara fungerade på läs/radering (en annan bieffekt) var det inte möjligt att göra ändringar. Ja, de behövdes inte, tk. allt stämde. Det ska se ut så här:

Windows Registerredigerare version 5.00 "Description" = "Tillhandahåller mappning för slutpunkter och andra RPC-tjänster." "DisplayName" = "Remote Procedure Call (RPC)" "ErrorControl" = dword: 00000001 "Group" = "COM Infrastructure" "ImagePath" = hex (2): 25,00,53,00,79,00,73, 00.74.00.65.00.6d, 00.52.00.6f, 00.6f, 00, \ 74.00.25.00.5c, 00.73.00.79.00.73.00 , 74,00,65,00, 0,3d, 0,3d, 0,3d, 0,3d 00,5c, 00,73, \ 00,76,00,63,00,68,00,6f, 00,73,00, 74,00,20,00,2d, 00,6b, 00,20,00 ,72,00,70,00, \ 63,00,73,00,73,00,00,00 "ObjectName" = "NT AUTHORITY \\ NetworkService "" Start "= dword: 00000002" Skriv "= dword: 00000010 " FailureActions "= hex: 00,00,00,00,00,00,00,00,00,00,00,00,01 , 00,00,00,00,00,00, \ 00,02,00 ,00,00,60, ea, 00,00 "ServiceSidType" = dword: 00000001 "ServiceDll" = hex (2): 25,00 , 53,00,79,00,73,00,74,00,65, 00,6d, 00,52,00,6f, 00,6f, \ 00,74,00,25,00,5c, 00, 73,00,79,00,73,00,74,00,65,00 ,6d, 00,33,00,32,00,5c, 00, \ 72,00,70,00,63,00,73 , 00,73,00,2e, 00,64,00,6c, 00, 6c, 00,00,00 "Säkerhet" = hex: 01,00,14,80, a8,00,00,00, b4, 00.00,00,14,00,00,00,30,00,00,00 ,02, \ 00,1c, 00,01,00,00,00,02,80,14,00, ff, 01 , 0f, 00.01.01.00.00.00.00.00.01.00.00, \ 00.00.00, \ 00.00.0. .05.00, 00,00,00,00,14,00,8d, 00,02,00,01,01,00,00,00,00,00, \ 05,0b, 00,00,00,00,00,18 , 00 , ff, 01.0f, 00.01.02.00.00.00.00.00.05.20.00.00.00, \ 20.02.00.00.00.00.18, 00.8d, 00.02.00.01.02,02.02.02.02.02.002.02 .00.00.00.14.00 .9d, 00,00,00,01,01,00,00,00,00,00,05,04,00,00,00,00,00, \ 18,00,9d, 00,00,00, 01.02,00,00,00,00,00,05,20,00,00,00,21,02,00,00,01,01,00 \ 00,00,00,00, 05,12 , 00,00,00,01,01,00,00,00,00,00,05,12,00,00,00 "0" = "Root \\ LEGACY_RPCSS \\ 0000" "Count" = dword: 00000001 "NextInstance" = dword: 00000001

Parametervärde Start kan skilja sig åt. Du kan fortfarande ändra registret, men du måste starta från MS ERD-befälhavare.

Jag kommer helt enkelt att beskriva nästa steg punkt för punkt. Den allmänna idén är att ersätta filer med kända fungerande. De kan tas från en annan maskin eller från Windows-distributionen (som jag gjorde).

  • Starta konsolen (Start> Kör: cmd)
  • cd z: \ i386(det finns en Windows-distribution)
  • expandera explorer.ex_% TEMP% \ explorer.exe
  • expandera svchost.ex_% TEMP% \ svchost.exe
  • Starta Aktivitetshanteraren (Ctrl + Shift + Esc)
  • Stoppa exlporer.exe-processen
  • copy% TEMP% \ explorer.exe% SYSTEMROOT% / y
  • Stoppa alla svchost.exe-processer. Uppmärksamhet! Efter det har du 60 sekunder på dig innan du startar om maskinen.
  • copy% TEMP% \ svchost.exe% systemrot% \ system32 / y

Detta trick gav inte heller resultat. Ett annat alternativ är att köra en genomsökning av alla skyddade systemfiler och ersätta de felaktiga versionerna med de korrekta. I konsolen, kör:

sfc / PURGECACHE- Rensa filcache och kontrollera filer omedelbart
sfc / SCANONCE- Engångskontroll vid nästa start

Det hjälpte inte .. Sedan ett helt brutalt drag - återställande av säkerhetsparametrar. Återigen i konsolen:

secedit / configure / cfg% windir% \ reparation \ secsetup.inf / db secsetup.sdb / verbose

Efter omstart började datorn fungera, de grundläggande tjänsterna startade. En ny jamb dök upp (eller kanske var det från första början): åtminstone startade inte diskhanteringshanteraren och Windows Installer under mitt konto. Tillträde beviljas ej. Du kan återställa åtkomsträttigheter till "standard" systemdisken via konsolen:

secedit / configure / db% TEMP% \ temp.mdb / Cfg% WINDIR% \ inf \ defltwk.inf / areas filestore

Sedan måste du manuellt definiera rättigheterna för varje konto till eller återskapa dem, beroende på vilket som är lättare.

I mitt fall tilldelade jag helt enkelt samma rättigheter till hela systemdisken och tog katalogåtkomst som referens. Jag lade till mitt konto till referensen i domänen med fullständiga rättigheter till disken. Kanske är detta fel ur säkerhetssynpunkt, men jag har inte tid att gräva i varje katalog separat.

Vad mer kunde göras

Medan datorn var "sjuk" fanns inte detta i registret:

"ActiveService" = "RpcSs"

Kanske att lägga till det manuellt skulle på något sätt förändra situationen.

Försök att manuellt starta tjänsten, till exempel genom kommandot " net start rcpss"slutade med misstag" Fel 5: åtkomst nekad". Jag antar att åtkomst nekas eftersom tjänsten måste köras under systemkontot -" NT AUTHORITY ". Registret har denna parameter:

"ObjectName" = "NT AUTHORITY \\ NetworkService"

Jag skulle försöka ange administratörskontot här och starta tjänsten igen. Men det här är bara en idé som inte levde för att se genomförandet.

Ett annat alternativ: använda KiTrap0D-exploateringen för att få konsolen med systemrättigheter. Detta utnyttjande rapporterades i. Det binära i sig. Men jag har nya Windows-uppdateringar, så det ser ut som att denna exploatering inte längre fungerar.

Relaterat material:







2021 gtavrl.ru.