Вызов удаленных процедур (rpc - Remote Procedure Call). Вызов удаленных процедур (RPC) Структуры сообщений протокола

Идея вызова удаленных процедур (Remote Procedure Call - RPC) состоит в расширении хорошо известного и понятного механизма передачи управления и данных внутри программы, выполняющейся на одной машине, на передачу управления и данных через сеть. То есть, клиентское приложение обращается к процедурам, хранящимся на сервере. Средства удаленного вызова процедур предназначены для облегчения организации распределенных вычислений. Наибольшая эффективность использования RPC достигается в тех приложениях, в которых существует интерактивная связь между удаленными компонентами с небольшим временем ответов и относительно малым количеством передаваемых данных. Такие приложения называются RPC-ориентированными.

Характерными чертами RPC являются:

Асимметричность, то есть одна из взаимодействующих сторон является инициатором;

Синхронность, то есть выполнение вызывающей процедуры приостанавливается с момента выдачи запроса и возобновляется только после возврата из вызываемой процедуры.

Существует несколько реализаций процедур удаленного вызова в различных операционных системах. В операционной системе UNIX используется процедура под одноименным названием (Remote Procedure Call - RPC). Данная процедура внедрена в ядро системы. Ее выполнение обеспечивается протоколом RPC. В операционных системах Windows удаленный вызов процедур начал развиваться на базе механизмов OLE, которые постепенно развились в технологию DCOM (Distributed Component Object Model). Данная технология позволяет создавать достаточно мощные распределенные сетевые вычислительные среды. В технологии используются фирменные протоколы Microsoft.

Механизм работы RPC

Перед непосредственным вызовом на клиентской и серверной стороне должны быть созданы специальные структуры (процедуры, файлы) - это так называемые клиентский стаб (stub) и серверный скелетон (skeleton), которые необходимы для корректной работы RPC. Чаще всего, они генерируются автоматически специальными утилитами по основному коду программы.

При удаленном вызове процедуры в распределенной системе происходят следующие действия:

1. Процедура клиента вызывает стаб как обычную процедуру. Стаб упаковывает параметры (маршализация, marshaling).

2. Стаб обращается к ядру ОС.

3. Ядро посылает сообщение на удаленную машину (ядру удаленного ПК).

4. Передача полученного сообщения скелетону серверного процесса.

5. Распаковка параметров (демаршализация, unmarshaling). Вызов требуемой процедуры.

6. Процедура на сервере выполняется. Возвращает результаты скелетону.

7. Скелетон упаковывает результат.

8. Передача результата ядру.

9. Ядро сервера передает сообщение по сети ядру клиента.

10. Ядро клиента обращается к стабу. Стаб распаковывает полученный результат.

11. Передача от стаба клиентскому процессу.

Служба "Удаленный вызов процедур (RPC)" в ОС Windows

Для того чтобы понять важность механизма удаленного вызова процедур, можно рассмотреть хотя бы список утилит и служб, которые не работают без RPC в ОС Windows 2000. Фактически, отключение службы RPC в указанной среде приводит к краху всей системы. Итак, от службы "Удаленный вызов процедур (RPC)" зависят:

1. Telnet - позволяет удаленному пользователю войти в систему и запустить программы консоли с помощью командной строки.

2. Windows Installer - устанавливает, удаляет или восстанавливает программное обеспечение в соответствии с инструкциями файлов MSI.

3. Агент политики IPSEC - управляет политикой IP-безопасности и запускает ISAKMP/Oakley (IKE) и драйвер IP-безопасности.

4. Диспетчер очереди печати - загружает в память файлы для последующей печати.

5. Защищенное хранилище - обеспечивает защищенное хранение секретных данных, таких как закрытые ключи, для предотвращения несанкционированного доступа служб, процессов или пользователей.

6. Инструментарий управления Windows - предоставляет информацию об управлении системой.

7. Клиент отслеживания изменившихся связей - посылает оповещения о файлах, перемещенных между томами NTFS в сетевом домене.

8. Координатор распределенных транзакций - координация транзакций, распределенных по нескольким базам данных, очередям сообщений, файловым системам или другим защищенным диспетчерам ресурсов транзакций.

9. Маршрутизация и удаленный доступ - предлагает услуги маршрутизации организациям в локальной и глобальной сетях.

10. Планировщик заданий - позволяет выполнять программы в назначенное время.

11. Сетевые подключения - управляет объектами папки "Сеть и удаленный доступ к сети", отображающей свойства локальной сети и подключений удаленного доступа.

12. Система событий COM+ - автоматическое распространение событий подписавшимся компонентам COM.

13. Служба индексирования - индексирование для быстрого поиска.

14. Служба сообщений - посылает и получает сообщения, переданные администраторами или службой оповещений.

15. Служба факсов - помогает отправлять и принимать факсимильные сообщения.

16. Съемные ЗУ - управляет съемными носителями, дисками и библиотеками.

17. Телефония - обеспечивает поддержку Telephony API (TAPI) для программ, управляющих телефонным оборудованием и голосовыми IP-подключениями на этом компьютере, а также через ЛВС - на серверах, где запущена соответствующая служба.

RMI-приложения

Вызов Удаленных Методов Remote Method Invocation (RMI) является реализацией идей RPC для языка программирования Java.

RMI - продукт компании JavaSoft, разработанный для Java и интегрированный в JDK 1.1 и выше. RMI реализует распределенную модель вычислений и обеспечивает средства коммуникации между Java-программами (виртуальными Java-машинами), выполняющимися на одном или нескольких удаленных компьютерах. RMI позволяет клиентским и серверным приложениям через сеть вызывать методы клиентов/серверов, выполняющихся на виртуальных Java-машинах. Основное преимущество RMI заключается в том, что он предоставляет программисту программируемый интерфейс более высокого уровня, который позволяет передавать ссылку на удаленный объект в качестве аргумента или возвращать ее в качестве результата. RMI требует, чтобы на обоих концах соединения выполнялись Java-программы. Сетевое соединение достигается с использованием TCP/IP-протокола. Архитектура RMI приведена на рис. "Архитектура RMI".

Client Stub (переходник для клиента - некая сущность на клиенте, которая обеспечивает функции приема/передачи), и Server Skeleton (переходник для сервера - некая сущность на сервере, которая обрабатывает удаленные вызовы) порождены от общего интерфейса, но различаются тем, что Client Stub служит просто для подсоединения к RMI Registry, а Server Stub используется для связи непосредственно с функциями сервера.

RMI является в действительности новым видом брокера объектных запросов, который строится на объектной модели Java. Как и ORB, RMI вводит пять ключевых моментов:

1. Позволяет перемещать код в дополнение к данным.

2. Практически обеспечивает безопасность выполнения загружаемого кода.

3. Позволяет передавать объекты по значению.

4. Использует Java как язык определения интерфейса и как язык реализации.

5. Использует именующую схему на базе унифицированного указателя ресурсов Uniform Resource Locator (URL).

При этом производится преобразование объектов в последовательную форму - в поток байтов, передаваемых как параметр в сообщении с помощью протокола TCP/IP.

Интерфейсы RMI можно разделить на 4 категории:

Ядро RMI - определяет интерфейсы, необходимые для выполнения вызовов удаленных методов;

Служба именования RMI - определяет интерфейсы и классы, позволяющие получить ссылки на серверные объекты по имени;

Безопасность RMI - определяет новый менеджер безопасности RMI и интерфейсы загрузчика классов (RMI расширяет механизм загрузки классов Java по требованию на загрузку стаба);

Маршализация (упаковка запроса, включая параметры, возвращаемое значение, сам запрос, в стандартный формат, пригодный для передачи по сети) - RMI определяет интерфейсы нижнего уровня для маршализации удаленных объектов, которые используются для записи объектов Java в поток и для чтения объекта из потока.

JavaSoft и OMG работают над сближением объектных моделей RMI и CORBA. Это сближение происходит в двух областях:

RMI через IIOP. JavaSoft разрабатывает версию RMI, которая работает поверх транспорта IIOP. IIOP предоставляет следующие преимущества для RMI:

1. Встроенную поддержку для распространения транзакций.

2. Поддержку брандмауэра на основе ORB с помощью заместителя IIOP (без HTTP-туннелирования).

3. Взаимодействие с объектами, написанными на других языках через подмножество RMI/IDL.

4. Открытый стандарт распределенных объектов.

RMI/IDL. Стандарт CORBA Java в IDL является стандартом сближения CORBA/RMI. Он позволяет программистам Java определять интерфейсы CORBA c помощью семантики Java RMI вместо CORBA IDL. Компилятор использует эту семантику для автоматического создания CORBA IDL, стабов и скелетонов. Подмножество RMI/IDL позволяет программам RMI вызываться многоязычными клиентами CORBA с помощью IIOP; он также позволяет RMI-программам вызывать объекты CORBA, написанные на других языках.

RMI через IIOP кажется хорошим решением для системы CORBA/Java, поскольку объединяет две мощные технологии. Основным достоинством RMI является то, что с его помощью можно наиболее быстро и просто создать небольшую распределенную систему в чисто Java-среде. Основным недостатком RMI является невозможность интегрирования этого механизма с существующими приложениями.

Сравнение распределенных и нераспределенных Java-программ

Разработчики RMI стремились сделать использование распределенных Java-объектов таким же, как и использование локальных объектов. В следующей таблице перечислены некоторые важные отличия.

Интерфейсы в RMI

Архитектура RMI основана на одном важном принципе: определение поведения и реализация этого поведения считаются разными понятиями. RMI дает возможность разделить и выполнить на разных JVM код, определяющий поведение, и код, реализующий поведение.

Это соответствует требованиям распределенных систем, в которых клиенты знают об определениях служб, а серверы предоставляют эти службы. Конкретно в RMI определение удаленной службы кодируется при помощи интерфейса Java. Реализация удаленной службы кодируется в классе. Таким образом, ключ к пониманию RMI - помнить, что интерфейсы определяют поведение, а классы определяют реализацию.

Помните, что интерфейсы Java не содержат исполняемого кода. RMI поддерживает два класса, реализующих один и тот же интерфейс. Первый класс является реализацией поведения и исполняется на сервере. Второй класс работает как промежуточный интерфейс для удаленной службы и исполняется на клиентской машине.

Клиентская программа вызывает методы прокси-объекта, RMI передает запрос на удаленную JVM и направляет его в реализацию объекта. Любые возвращаемые из реализации значения передаются назад в прокси-объект и затем в клиентскую программу.

Уровни архитектуры RMI

Реализация RMI, по существу, состоит из трех абстрактных уровней. Первый - это уровень заглушки и скелета, расположенный непосредственно перед разработчиком. Этот уровень перехватывает вызовы методов, произведенные клиентом при помощи переменной-ссылки на интерфейс, и переадресует их в удаленную службу RMI.

Следующий уровень - уровень удаленной ссылки. Этот уровень понимает, как интерпретировать и управлять ссылками на удаленные объекты служб. В JDK 1.1 этот уровень соединяет клиентов с удаленными объектами служб, которые исполняются на сервере. Это соединение является связью типа один к одному (однонаправленное соединение). В Java 2 SDK этот уровень был расширен поддержкой активации пассивных удаленных объектов при помощи технологии Remote Object Activation.

Транспортный уровень основан на соединениях TCP/IP между сетевыми машинами. Он обеспечивает основные возможности соединения и некоторые стратегии защиты от несанкционированного доступа. При использовании уровневой архитектуры каждый из уровней может быть изменен или заменен без воздействия на остальную систему. Например, транспортный уровень может быть заменен протоколом UDP/IP без изменения остальных уровней.

Поиск удаленных объектов

При рассмотрении архитектуры RMI возникает вопрос: "Как клиент находит удаленную службу RMI?". Клиенты находят удаленные службы, используя службу имен или каталогов. Как клиент может найти службу, используя службу? Но это действительно так. Служба имен или каталогов исполняется на хорошо известном хосте и имеет известный номер порта (хорошо известный означает, что все в организации знают об этом).

RMI может использовать много различных служб каталогов, включая Java Naming and Directory Interface (JNDI). RMI и сама включает в себя простую службу, называемую реестром RMI, rmiregistry. Реестр RMI работает на каждой машине, содержащей объекты удаленных служб и принимающей запросы на обслуживание, по умолчанию используя порт 1099. На хосте программа сервера создает удаленную службу, предварительно создавая локальный объект, реализующий эту службу. Затем она экспортирует этот объект в RMI. Как только объект экспортирован, RMI создает службу прослушивания, ожидающую соединения с клиентом и запроса службы. После экспорта, сервер регистрирует объект в реестре RMI, используя общедоступное имя.

На стороне клиента к реестру RMI доступ обеспечивается через статический класс Naming. Он предоставляет метод lookup(), который клиент использует для запросов к реестру. Метод lookup() принимает URL, указывающий на имя хоста и имя требуемой службы. Метод возвращает удаленную ссылку на обслуживающий объект. URL принимает следующий вид:

rmi:// [:] /
где host_name - это имя, распознаваемое в локальной сети (LAN), или DNS-имя в сети Internet. Необходимо только указать name_service_port, если служба имен исполняется на порте, отличном от принимаемого по умолчанию 1099.

Использование RMI

Рабочая RMI-система состоит из нескольких частей: определение интерфейсов для удаленных служб, реализация удаленных служб, файлы заглушки и скелета, сервер, предоставляющий удаленные службы, служба имен RMI, дающая возможность клиентам найти удаленные службы, поставщик файла классов (HTTP или FTP-сервер), клиентская программа, которая нуждается в удаленных службах.

Если предположить, что RMI-система уже спроектирована, для ее создания необходимо выполнить следующие шаги:

1. Написать и откомпилировать Java-код для интерфейсов.

2. Написать и откомпилировать Java-код для классов реализации.

3. Создать файлы классов заглушки и скелета из классов реализации.

4. Написать Java-код программы хоста для удаленного обслуживания.

5. Разработать Java-код для клиентской программы RMI.

6. Установить и запустить RMI-систему.

Пример RMI - приложения

Первым шагом является написание и компилирование Java-кода для интерфейсов служб. Интерфейс Calculator определяет все удаленные возможности, предлагаемые службой:

public interface Calculator extends java.rmi.Remote {
public long add(long a, long b) throws java.rmi.RemoteException;
public long sub(long a, long b) throws java.rmi.RemoteException;
public long mul(long a, long b) throws java.rmi.RemoteException;
public long div(long a, long b) throws java.rmi.RemoteException;
}

Обратите внимание, что этот интерфейс расширяет интерфейс Remote, и в сигнатуре каждого метода определяется, что он может генерировать объект RemoteException. Вообще, объект называется удаленным, если он реализует интерфейс Remote. "Реализует" в смысле заголовка (public interface Calculator extends java.rmi.Remote), никаких методов в этом интерфейсе нет. Это - метка. Теперь необходимо написать реализацию удаленной службы. Ниже приведен класс CalculatorImpl:

public class CalculatorImpl extends java.rmi.server.UnicastRemoteObject
implements Calculator {
// Реализации должны иметь явный конструктор для того, чтобы объявить
// исключительную ситуацию RemoteException
public CalculatorImpl()
throws java.rmi.RemoteException {
super();
}
public long add(long a, long b) throws java.rmi.RemoteException {
return a + b;
}
public long sub(long a, long b) throws java.rmi.RemoteException {
return a - b;
}
public long mul(long a, long b) throws java.rmi.RemoteException {
return a * b;
}
public long div(long a, long b) throws java.rmi.RemoteException {
return a / b;
}
}

Класс реализации использует Unicast RemoteObject для присоединения к системе RMI. В данном примере класс реализации непосредственно расширяет UnicastRemoteObject. Это не является обязательным требованием. Класс, не расширяющий UnicastRemoteObject, может использовать свой метод exportObject() для присоединения к RMI. Если класс расширяет UnicastRemoteObject, он должен обеспечить конструктор, объявляющий, что он может сгенерировать объект RemoteException. Если этот конструктор вызывает метод super(), он активизирует код в UnicastRemoteObject, который выполняет RMI-соединение и инициализацию удаленного объекта.

Удаленные службы RMI должны быть помещены в процесс сервера. Класс CalculatorServer является очень простым сервером, предоставляющим простые элементы для размещения.

import java.rmi.Naming;

public class CalculatorServer {
public CalculatorServer() {
try {
Calculator c = new CalculatorImpl();
Naming.rebind("
rmi://localhost:1099/
CalculatorService", c);
} catch (Exception e) {
System.out.println("Trouble: " + e);
}
}
new CalculatorServer();
}
}

Исходный код клиента, к примеру, может быть следующий:

import java.rmi.Naming;
import java.rmi.RemoteException;
import java.net.MalformedURLException;
import java.rmi.NotBoundException;
public class CalculatorClient {
public static void main(String args) {
try {
Calculator c = (Calculator)
Naming.lookup(
"rmi://remotehost
/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 (MalformedURLException murle) {
System.out.println();
System.out.println(
"MalformedURLException");
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);
}
catch (
java.lang.ArithmeticException
ae) {
System.out.println();
System.out.println(
"java.lang.ArithmeticException");
System.out.println(ae);
}
}
}

Теперь можно запускать систему. Сделать это можно (после получения соответствующих class-файлов и размещения их на одном или разных ПК) так:

1. Запустить реестр RMI ("rmiregistry").

2. Запустить сервер ("java CalculatorServer").

3. Запустить клиент ("java CalculatorClient").

Если все пройдет хорошо, вы увидите следующую информацию:

1
9
18
3

Вот и все - работающая система RMI готова. Даже если вы запустили три консоли на одном и том же компьютере, RMI использует стек протоколов TCP/IP вашей сети для взаимодействия между тремя отдельными JVM. Это вполне законченная RMI-система.

Распространение классов RMI

Для запуска RMI-приложения файлы поддерживающих классов должны быть расположены в таких местах, где бы они могли быть найдены сервером и клиентами.

Для сервера должны быть доступны (для загрузчика классов) классы:

Реализации удаленных служб

Скелеты для классов реализации (только для серверов, основанных на JDK 1.1)

Заглушки для классов реализации

Все остальные классы сервера

Для клиента должны быть доступны (для загрузчика классов) классы:

Определения интерфейса удаленной службы

Заглушки для классов, реализующих удаленную службу

Классы сервера для объектов, используемых клиентом (таких, как возвращаемое значение)

Все остальные классы клиента

Если вы знаете, какие файлы должны быть размещены на различных узлах сети, то сделать их доступными для каждого загрузчика классов JVM не составит труда.

Распределенная сборка мусора

Одним из преимуществ программирования для платформы Java является отсутствие беспокойства о распределении памяти. JVM имеет автоматический сборщик мусора, который освобождает память, занимаемую любым объектом, который больше не используется исполняющейся программой. Одним из требований к разработке RMI была ее бесшовная интеграция в язык программирования Java, включая и сборку мусора. Разработка эффективного сборщика мусора для одной машины является тяжелой задачей; разработка распределенного сборщика мусора является очень тяжелой задачей. RMI-система обеспечивает подсчитывающий ссылки алгоритм распределенной сборки мусора, основанный на сетевых объектах, используемых в Modula-3. Эта система при работе следит за тем, какие клиенты запросили доступ к удаленным объектам, выполняющимся на сервере. Когда появляется ссылка, сервер помечает объект как "грязный", а когда клиент удаляет ссылку, объект помечается как "чистый".

Интерфейс к DGC (распределенный сборщик мусора) скрыт на уровне заглушек и скелетов. Однако удаленный объект может реализовать интерфейс java.rmi.server.Unreferenced и получить уведомление через метод unreferenced, когда нет больше ни одного клиента, содержащего живую ссылку. В дополнение к механизму подсчета ссылок живая ссылка в клиенте имеет срок аренды с указанным временем. Если клиент не обновляет соединение к удаленному объекту до истечения срока аренды, ссылка считается мертвой и удаленный объект может быть утилизирован сборщиком мусора. Время аренды управляется системным свойством java.rmi.dgc.leaseValue. Его значение указывается в миллисекундах и по умолчанию равно 10 минутам. Из-за такой семантики сборки мусора, клиент должен быть подготовлен для работы с объектами, которые могут "исчезать".

Заключение

Технология Remote Method Invocation (RMI), впервые представленная в JDK 1.1, продвинула сетевое программирование на более высокий уровень. Хотя RMI относительно проста в использовании и не лишена недостатков, она является необыкновенно мощной технологией и раскрывает перед обычным Java-программистом полностью новую парадигму - мир распределенных объектных вычислений.


Лекция 4

4.1 Концепция удаленного вызова процедур

Идея вызова удаленных процедур (Remote Procedure Call - RPC) состоит в расширении хорошо известного и понятного механизма передачи управления и данных внутри программы, выполняющейся на одной машине, на передачу управления и данных через сеть. Средства удаленного вызова процедур предназначены для облегчения организации распределенных вычислений. Наибольшая эффективность использования RPC достигается в тех приложениях, в которых существует интерактивная связь между удаленными компонентами с небольшим временем ответов и относительно малым количеством передаваемых данных. Такие приложения называются RPC-ориентированными.

Характерными чертами вызова локальных процедур являются: асимметричность, то есть одна из взаимодействующих сторон является инициатором; синхронность, то есть выполнение вызывающей процедуры при останавливается с момента выдачи запроса и возобновляется только после возврата из вызываемой процедуры.

Реализация удаленных вызовов существенно сложнее реализации вызовов локальных процедур. Начнем с того, что поскольку вызывающая и вызываемая процедуры выполняются на разных машинах, то они имеют разные адресные пространства, и это создает проблемы при передаче параметров и результатов, особенно если машины не идентичны. Так как RPC не может рассчитывать на разделяемую память, то это означает, что параметры RPC не должны содержать указателей на ячейки нестековой памяти и что значения параметров должны копироваться с одного компьютера на другой. Следующим отличием RPC от локального вызова является то, что он обязательно использует нижележащую систему связи, однако это не должно быть явно видно ни в определении процедур, ни в самих процедурах. Удаленность вносит дополнительные проблемы. Выполнение вызывающей программы и вызываемой локальной процедуры в одной машине реализуется в рамках единого процесса. Но в реализации RPC участвуют как минимум два процесса - по одному в каждой машине. В случае, если один из них аварийно завершится, могут возникнуть следующие ситуации: при аварии вызывающей процедуры удаленно вызванные процедуры станут "осиротевшими", а при аварийном завершении удаленных процедур станут "обездоленными родителями" вызывающие процедуры, которые будут безрезультатно ожидать ответа от удаленных процедур.

Кроме того, существует ряд проблем, связанных с неоднородностью языков программирования и операционных сред: структуры данных и структуры вызова процедур, поддерживаемые в каком-либо одном языке программирования, не поддерживаются точно так же во всех других языках.


Эти и некоторые другие проблемы решает широко распространенная технология RPC, лежащая в основе многих распределенных операционных систем.

Базовые операции RPC

Чтобы понять работу RPC, рассмотрим вначале выполнение вызова локальной процедуры в обычной машине, работающей автономно. Пусть это, например, будет системный вызов

count=read (fd,buf,nbytes);

где fd – целое число;

buf – массив символов;

nbytes – целое число.

Чтобы осуществить вызов, вызывающая процедура заталкивает параметры в стек в обратном порядке. После того, как вызов read выполнен, он помещает возвращаемое значение в регистр, перемещает адрес возврата и возвращает управление вызывающей процедуре, которая выбирает параметры из стека, возвращая его в исходное состояние. Заметим, что в языке С параметры могут вызываться или по ссылке (by name), или по значению (by value). По отношению к вызываемой процедуре параметры-значения являются инициализируемыми локальными переменными. Вызываемая процедура может изменить их, и это не повлияет на значение оригиналов этих переменных в вызывающей процедуре.

Если в вызываемую процедуру передается указатель на переменную, то изменение значения этой переменной вызываемой процедурой влечет изменение значения этой переменной и для вызывающей процедуры. Этот факт весьма существенен для RPC.

Существует также другой механизм передачи параметров, который не используется в языке С. Он называется call-by-copy/restore и состоит в необходимости копирования вызывающей программой переменных в стек в виде значений, а затем копирования назад после выполнения вызова поверх оригинальных значений вызывающей процедуры.

Решение о том, какой механизм передачи параметров использовать, принимается разработчиками языка. Иногда это зависит от типа передаваемых данных. В языке С, например, целые и другие скалярные данные всегда передаются по значению, а массивы - по ссылке.

Идея, положенная в основу RPC, состоит в том, чтобы сделать вызов удаленной процедуры выглядящим по возможности также, как и вызов локальной процедуры. Другими словами - сделать RPC прозрачным: вызывающей процедуре не требуется знать, что вызываемая процедура находится на другой машине, и наоборот.

RPC достигает прозрачности следующим путем. Когда вызываемая процедура действительно является удаленной, в библиотеку помещается вместо локальной процедуры другая версия процедуры, называемая клиентским стабом (stub - заглушка). Подобно оригинальной процедуре, стаб вызывается с использованием вызывающей последовательности, так же происходит прерывание при обращении к ядру. Только в отличие от оригинальной процедуры он не помещает параметры в регистры и не запрашивает у ядра данные, вместо этого он формирует сообщение для отправки ядру удаленной машины.

Этапы выполнения RPC

Взаимодействие программных компонентов при выполнении удаленного вызова процедуры иллюстрируется рисунком 2.

Рисунок 2. Remote Procedure Call

После того, как клиентский стаб был вызван программой-клиентом, его первой задачей является заполнение буфера отправляемым сообщением. В некоторых системах клиентский стаб имеет единственный буфер фиксированной длины, заполняемый каждый раз с самого начала при поступлении каждого нового запроса. В других системах буфер сообщения представляет собой пул буферов для отдельных полей сообщения, причем некоторые из этих буферов уже заполнены. Этот метод особенно подходит для тех случаев, когда пакет имеет формат, состоящий из большого числа полей, но значения многих из этих полей не меняются от вызова к вызову.

Затем параметры должны быть преобразованы в соответствующий формат и вставлены в буфер сообщения. К этому моменту сообщение готово к передаче, поэтому выполняется прерывание по вызову ядра.

Когда ядро получает управление, оно переключает контексты, сохраняет регистры процессора и карту памяти (дескрипторы страниц), устанавливает новую карту памяти, которая будет использоваться для работы в режиме ядра. Поскольку контексты ядра и пользователя различаются, ядро должно точно скопировать сообщение в свое собственное адресное пространство, так, чтобы иметь к нему доступ, запомнить адрес назначения (а, возможно, и другие поля заголовка), а также оно должно передать его сетевому интерфейсу. На этом завершается работа на клиентской стороне. Включается таймер передачи, и ядро может либо выполнять циклический опрос наличия ответа, либо передать управление планировщику, который выберет какой-либо другой процесс на выполнение. В первом случае ускоряется выполнение запроса, но отсутствует мультипрограммирование.

На стороне сервера поступающие биты помещаются принимающей аппаратурой либо во встроенный буфер, либо в оперативную память. Когда вся информация будет получена, генерируется прерывание. Обработчик прерывания проверяет правильность данных пакета и определяет, какому стабу следует их передать. Если ни один из стабов не ожидает этот пакет, обработчик должен, либо поместить его в буфер, либо вообще отказаться от него. Если имеется ожидающий стаб, то сообщение копируется ему. Наконец, выполняется переключение контекстов, в результате чего восстанавливаются регистры и карта памяти, принимая те значения, которые они имели в момент, когда стаб сделал вызов receive.

Теперь начинает работу серверный стаб. Он распаковывает параметры и помещает их соответствующим образом в стек. Когда все готово, выполняется вызов сервера. После выполнения процедуры сервер передает результаты клиенту. Для этого выполняются все описанные выше этапы, только в обратном порядке.

Рисунок 3 показывает последовательность команд, которую необходимо выполнить для каждого RPC-вызова.

Рисунок 3. Этапы выполнения процедуры RPC

В состав операционной системы Windows любой модификации, начиная с версии ХР, входит служебный компонент, обозначаемый как RPC. Что это такое, рядовые пользователи в большинстве своем не знают, тем более, не догадываются, для чего нужна эта служба и как она работает. В связи с этим предлагается рассмотреть некоторые основные аспекты, связанные с самим компонентом, принципами его работы и областью использования без описания ненужных и сложных технических терминов. Отдельно остановимся на возможных ошибках службы и методиках их быстрого устранения.

Удаленные процедуры (вызов удаленных процедур): что это такое?

По всей видимости, многие пользователи, исходя из названия этого служебного компонента, уже сделали вывод о том, что это такое. Действительно, удаленные процедуры (вызов удаленных процедур) подразумевают какие-то действия при выполнении их не на локальном компьютере, а на удаленном (чаще всего на сервере).

То есть запрос формируется на одном терминале, затем передается на другой, где и выполняется, после чего на первый компьютер возвращается ответ (отчет) о выполнении. Но это только примитивное пояснение. На самом деле, все намного сложнее, поскольку здесь нужно учитывать протоколы передачи данных (UDP, TCP, HTTP) и многие другие механизмы.

Для чего нужна эта служба?

Несмотря на основное предназначение, удаленный вызов процедур RPC может применяться не на разных компьютерах, а на одном. В качестве самого простого примера можно привести вызов какой-то функции одной программы из другого приложения. Многие музыканты, работающие с виртуальными студиями и секвенсорами, знают, что в каждом таком приложении имеется собственный модуль редактирования или обработки аудио, который не всегда отвечает предъявляемым пользователем требованиям. И любая студия позволяет вместо него подключить любую другую внешнюю программу.

Например, в настройках секвенсора FL Studio можно указать другое приложение (скажем, Adobe Audition), которое для редактирования звуковых файлов (сэмплов) в среде основной программы будет использоваться по умолчанию. При этом подключение Adobe Audition к FL Studio будет осуществляться не через виртуальные хосты вроде VST, RTAS или DX, а непосредственно через задействование службы удаленного вызова процедур. Само собой разумеется, что этот пример не единственный, поскольку область применения описываемого компонента гораздо шире.

Очень часто данную службу связывают еще и с распределением вычислительной нагрузки на терминалы, между которыми устанавливается интерактивная связь. При этом, если производится равномерное распределение нагрузки на вычислительные ресурсы нескольких компьютеров, достичь максимальной производительности можно только при условии обмена небольшими объемами данных и быстрым откликом между компонентами.

Сбой при удаленном вызове процедуры: в чем причина?

К сожалению, из-за такой востребованности, появление сбоев и ошибок, связанных с этой службой, - достаточно частое явление.

Вследствие этого становится невозможным не только использование самого компонента. Иногда даже не удается получить доступ к некоторым системным настройкам, а Windows ХР так и вовсе «слетает», после чего восстановить ее до нормального работоспособного состояния бывает достаточно проблематично. Еще одна проблема - инструмент онлайн-восстановления DISM, входящий в состав операционной системы.

Именно с нарушениями в его работе связывают появление ошибки 1726, которая непосредственно влияет и на функционирование компонентов службы RPC.

Основными причинами таких сбоев называют вызов средств проверки или восстановления системы, когда процесс DISM активен или не может корректно завершить работу (например, при одновременном старте из двух командных консолей инструментов DISM и SFC); когда служба работает параллельно с обслуживанием компонентов RPC; когда служба блокируется антивирусным программным обеспечением.

Таким образом, если наблюдается сбой при удаленном вызове процедур в Windows 7 и выше, первое, что нужно сделать, - завершить работу DISM, перезагрузить компьютер и запустить службу заново. Если это не поможет, можно попытаться перейти в безопасный режим и на время проведения восстановления полностью отключить антивирусную защиту. На дополнительных мерах, которые помогают исправить любой сбой при удаленном вызове процедуры и в любой модификации Windows, остановимся отдельно. Пока же посмотрим на вопросы, связанные с отключением этого системного компонента (увы, но многие пользователи, не знающие сути вопроса, пытаются заниматься именно такими вещами).

Можно ли отключить службу RPC?

Итак, давайте посмотрим, насколько реально деактивировать вызов удаленных процедур. Удаленные процедуры, исходя из рекомендаций разработчиков, отключать нельзя ни в коем случае. Это важно! В принципе, сама сделать этого не позволит. Есть, конечно, некоторые обходные пути, подразумевающие использование дополнительного программного обеспечения, но по понятным причинам, названия таких приложений не приводятся, поскольку при их неправильном использовании вся система может прийти в негодность.

Последствия отключения процессов RPC

Даже если пользователю удастся каким-то образом отключить удаленные процедуры (вызов удаленных процедур), последствия, к сожалению, могут быть самыми непредсказуемыми. Как уже говорилось, Windows XP может вообще перестать работать, а в ОС рангом выше, как следствие, может появиться огромное количество системных сбоев, которые устранить не получится хотя бы по причине отсутствия доступа к критически важным настройкам и параметрам Windows, причем, даже в безопасном режиме или при старте со съемного носителя. Тем не менее, сбой при вызове удаленных процедур в Windows 10 или более ранних версиях операционной системы исправить можно. Метод не самый простой, поэтому при его использовании нужно быть очень внимательным.

Отключение локатора удаленного доступа

Итак, основную службу RPC отключать нельзя. Но, может быть, есть смысл деактивировать некоторые из ее сопутствующих компонентов? Да, действительно, если зайти в раздел системных служб и их компонентов (services.msc), в нем можно найти так называемый локатор RPC.

А вот его можно деактивировать, совершенно не опасаясь за появление катастрофических последствий. Войдя в редактирование его параметров, нужно остановить работу компонента и выставить тип запуска на отключенный. Программы, которые могут использовать удаленные процедуры, вызов удаленных процедур произведут и так (без его помощи).

Если по каким-то причинам установленные параметры не сработают, можно воспользоваться установочным диском Windows, при загрузке с него вызвать командную строку и вписать следующее:

  • cd X:\i386 (X - буква съемного диска);
  • expand explorer.ex_ %TEMP%\explorer.exe;
  • expand svchost.ex_ %TEMP%\svchost.exe.

После перезагрузки вызывается «Диспетчер задач», и в нем завершается затем в командной строке прописывается сочетание copy %TEMP%\explorer.exe %SYSTEMROOT% /y, после чего в «Диспетчере задач» завершаются абсолютно все процессы svchost. Теперь следует быть особо внимательным, поскольку по завершении процессов в течение всего лишь шестидесяти секунд в командной консоли нужно успеть прописать команду copy %TEMP%\svchost.exe %systemroot%\system32 /y.

Если у пользователя, например, в обычном или в безопасном режиме есть доступ к системному реестру, в редакторе (regedit) в ветке HKCC необходимо найти параметр CSConfigFlags и присвоить ему значение в виде нуля.

Устранение сбоя 1726

Наконец, устранение ошибки 1726 также производится через реестр. Но в данном случае в ветке HKLM нужно найти каталог RpcSs, а справа отредактировать значение параметра Start.

Его нужно поменять с четверки, обычно устанавливаемой по умолчанию, на двойку, после чего произвести рестарт системы.

Послесловие

Вот, собственно, и все, что касается вызова удаленных процедур. Удаленные процедуры, принципы работы этого компонента в расширенном варианте можно описывать еще очень долго, но упор в представленном материале был сделан на общем ознакомлении со службой и некоторых методах устранения ошибок и сбоев, которые она может вызывать в компьютерной системе. Рядовым пользователям придется запастись терпением и быть очень внимательными, поскольку одно неправильное действие в реестре может привести к полному крашу операционной системы.

Обратите внимание, что сбои такого типа никакими другими средствами вроде программ-оптимизаторов и настройщиков параметров операционных систем Windows не устраняются. При всем желании ни командная строка, ни, тем более, вмешательство в реестр на уровне редактирования ключей в таких программных пакетах не предусмотрено.

Цель данной статьи - обсудить терминологию. Статья - не о том, как и для чего, а только исключительно об использовании терминологии. Статья отражает мнение автора и не претендует на научность.

Вступление

Если вы работаете в области программирования распределенных систем или в интеграции систем , то большая часть изложенного здесь вам не в новинку.

Проблема возникает, когда встречаются люди, использующие разные технологии, и когда эти люди начинают технические разговоры. При этом часто возникает взаимное недопонимание, обусловленное терминологией. Я здесь попытаюсь свести воедино терминологии, используемые в разных контекстах.

Терминология

Четкой терминологии и классификации в этой области нет. Используемая ниже терминология является отражением модели, сложившейся у автора, то есть она строго субъективна. Любая критика и любые обсуждения приветствуются.

Я разделил терминологию на три области: RPC (Remote Procedure Call), Messaging и REST. Эти области имеют под собою исторические корни.

RPC

RPC технологии - наиболее старые технологии. Наиболее яркие представители RPC, это - CORBA и DCOM .

В те времена в основном приходилось связывать системы в быстрых и относительно надежных локальных сетях. Главная идея RPC была в том, чтобы сделать вызов удаленных систем очень похожим на вызов функций внутри программы. Вся механика удаленных вызовов пряталась от программиста. По крайней мере её пытались спрятать. Программисты во многих случаях вынуждены были работать на более глубоком уровне, где появлялись термины маршалинг (marshalling ) и unmarshalling (как это по-русски?), что по сути означало сериализацию. Обычные вызовы функций внутри процессов обрабатывались на вызывающей стороне в Proxy , а на стороне системы, выполняющей функцию, в Dispatcher . В идеале ни вызывающая система, ни обрабатывающая система не занимались тонкостями передачи данных между системами. Все эти тонкости сосредотачивались в связке Proxy - Dispatcher, код которых генерировался автоматически.

Поэтому вы не заметите, не должны заметить, никакой разницы между вызовом локальной функции и вызовом удаленной функции.
Сейчас наблюдается своеобразный ренесанс RPC, наиболее яркие представители которого: Google ProtoBuf, Thrift, Avro.

Messaging

С течением времени выяснилось, что попытка оградить программиста от того, что вызываемая функция все же отличается от локальной, не привела к желаемому результату. Детали реализации и принципиальные отличия распределенных систем были слишком велики, чтобы решаться с помощью автоматически генерируемого кода Proxy. Постепенно пришло понимание, что факт того, что системы связывает ненадежная, медленная, низкоскоростная среда, должен быть явно отражен в коде программы.

Появились технологии веб-сервисов . Мы стали говорить ABC: Address, Binding, Contract . Не совсем понятно, почему появились контракты, которые по сути являются Envelope (конвертами) для входных аргументов. Контракты чаще усложняют всю модель, чем упрощают ее. Но… неважно.

Теперь программист явным образом создавал сервис (Service ) или клиента (Client ), вызывающего сервис. Сервис представлял из себя набор операций (Operation ), каждая из которых на входе принимала запрос (Request ) и выдавала ответ (Response ). Клиент явным образом посылал (Sent ) запрос, сервис явным образом получал (Receive ) его и отвечал (Sent), высылая ответ. Клиент получал (Receive) ответ и на этом вызов завершался.

Так же, как и в RPC, где-то здесь работали Proxy и Dispatcher. И как прежде их код генерировался автоматически и программисту не надо было в нем разбираться. Разве только что, клиент явным образом использовал классы из Proxy.

Запросы и ответы явным образом преобразуются к формату, предназначенному для передачи по проводам. Чаще всего это массив байт. Преобразование называется Serialization и Deserialization и иногда прячется в коде Proxy.
Кульминация messaging проявилась в появлении парадигмы ESB (Enterprise Service Bus) . Никто толком не может сформулировать, что это такое, но все сходятся на том, что данные по ESB движутся в виде сообщений.

REST

В постоянной борьбе со сложностью кода, программисты сделали очередной шаг и создали REST .

Основной принцип REST в том, что операции-функции резко ограничили и оставили только набор операций CRUD: Create - Read - Update - Delete . В этой модели все операции всегда применяются к некоторым данным. Имеющихся в CRUD операций достаточно для большей части приложений. Так как REST технологии в большинстве случаев подразумевают использование протокола HTTP, то команды CRUD отразились на команды HTTP (Post - Get - Put - Delete ) . Постоянно утверждается, что REST не обязательно привязан к HTTP. Но на практике повсеместно используется отражение сигнатур операций на синтаксис HTTP команд. К примеру, вызов функции

EntityAddress ReadEntityAddress(string param1, string param2)

Выразится в таком виде:

GET: entityAddress?param1=value1¶m2=value2

Заключение

Прежде, чем начинать дискуссию по распределенным системам или по интеграции, определитесь с терминологией. Если Proxy всегда будет означать одно и то же в разных контекстах, то, к примеру, request мало что будет значить в терминах RPC, а marshalling вызовет недоумение при обсуждении REST технологий.

Удалённый вызов процедур (или Вызов удалённых процедур ) (от англ. Remote Procedure Call (RPC) ) - класс технологий, позволяющих компьютерным программам вызывать функции или процедуры в другом адресном пространстве (как правило, на удалённых компьютерах). Обычно, реализация RPC технологии включает в себя два компонента: сетевой протокол для обмена в режиме клиент-сервер и язык сериализации объектов (или структур, для необъектных RPC). Различные реализации RPC имеют очень отличающуюся друг от друга архитектуру и разнятся в своих возможностях: одни реализуют архитектуру SOA , другие CORBA или DCOM . На транспортном уровне RPC используют в основном протоколы TCP и UDP , однако, некоторые построены на основе HTTP (что нарушает архитектуру ISO/OSI, так как HTTP изначально не транспортный протокол).

Реализации

Существуют множество технологий, обеспечивающих RPC:

  • Sun RPC (бинарный протокол на базе TCP и UDP и XDR) RFC-1831 второе название ONC RPC RFC-1833
  • .Net Remoting (бинарный протокол на базе TCP, UDP, HTTP)
  • SOAP - Simple Object Access Protocol (текстовый протокол на базе HTTP) см. спецификацию: RFC-4227
  • XML RPC (текстовый протокол на базе HTTP) см. спецификацию: RFC-3529
  • Java RMI - Java Remote Method Invocation - см. спецификацию: http://java.sun.com/j2se/1.5.0/docs/guide/rmi/index.html
  • JSON-RPC JavaScript Object Notation Remote Procedure Calls (текстовый протокол на базе HTTP) см. спецификацию: RFC-4627
  • DCE/RPC - Distributed Computing Environment / Remote Procedure Calls (бинарный протокол на базе различных транспортных протоколов, в том числе TCP/IP и Named Pipes из протокола SMB/CIFS)
  • DCOM - Distributed Component Object Model известный как MSRPC Microsoft Remote Procedure Call или «Network OLE» (объектно-ориентированное расширение DCE RPC, позволяющее передавать ссылки на объекты и вызывать методы объектов через таковые ссылки)

Принцип

Идея вызова удалённых процедур (Remote Procedure Call - RPC) состоит в расширении хорошо известного и понятного механизма передачи управления и данных внутри программы, выполняющейся на одной машине, на передачу управления и данных через сеть. Средства удалённого вызова процедур предназначены для облегчения организации распределённых вычислений и создания распределенных клиент-серверных информационных систем. Наибольшая эффективность использования RPC достигается в тех приложениях, в которых существует интерактивная связь между удалёнными компонентами с небольшим временем ответов и относительно малым количеством передаваемых данных. Такие приложения называются RPC-ориентированными.

Реализация удалённых вызовов существенно сложнее реализации вызовов локальных процедур. Можно обозначить следующие проблемы и задачи, которые необходимо решить при реализации RPC:

  • Так как вызывающая и вызываемая процедуры выполняются на разных машинах, то они имеют разные адресные пространства, и это создает проблемы при передаче параметров и результатов, особенно если машины находятся под управлением различных операционных систем или имеют различную архитектуру (например, используется прямой или обратный порядок байтов). Так как RPC не может рассчитывать на разделяемую память, то это означает, что параметры RPC не должны содержать указателей на ячейки нестековой памяти и что значения параметров должны копироваться с одного компьютера на другой. Для копирования параметров процедуры и результата выполнения через сеть выполняется их сериализация .
  • В отличие от локального вызова удалённый вызов процедур обязательно использует транспортный уровень сетевой архитектуры (например TCP), однако это остается скрытым от разработчика.
  • Выполнение вызывающей программы и вызываемой локальной процедуры в одной машине реализуется в рамках единого процесса. Но в реализации RPC участвуют как минимум два процесса - по одному в каждой машине. В случае, если один из них аварийно завершится, могут возникнуть следующие ситуации: при аварии вызывающей процедуры удалённо вызванные процедуры станут «осиротевшими», а при аварийном завершении удалённых процедур станут «обездоленными родителями» вызывающие процедуры, которые будут безрезультатно ожидать ответа от удалённых процедур.
  • Существует ряд проблем, связанных с неоднородностью языков программирования и операционных сред: структуры данных и структуры вызова процедур, поддерживаемые в каком-либо одном языке программирования, не поддерживаются точно так же во всех других языках. Таким образом имеется проблема совместимости, до сих пор не решённая ни с помощью введения одного общепринятого стандарта, ни с помощью реализации нескольких конкурирующих стандартов на всех архитектурах и во всех языках.

Подсистемы

  • Транспортная подсистема

Управление исходящими и входящими соединениями. - поддержка понятия «граница сообщения» для транспортных протоколов, не поддерживающих его непосредственно (TCP). - поддержка гарантированной доставки для транспортных протоколов, не поддерживающих ее непосредственно (UDP).

  • Пул потоков (только для вызываемой стороны). Предоставляет контекст выполнения для вызванного по сети кода.
  • Маршалинг (также называется «сериализация»). Упаковка параметров вызовов в поток байт стандартным образом, не зависящим от архитектуры (в частности, от порядка байт в слове). В частности, ему могут подвергаться массивы, строки и структуры, на которые указывают параметры-указатели.
  • Шифрование пакетов и наложение на них цифровой подписи .
  • Аутентификация и авторизация. Передача по сети информации, идентифицирующей субъект, осуществляющий вызов.

В некоторых реализациях RPC (.NET Remoting) границы подсистем являются открытыми полиморфными интерфейсами, и возможно написать свою реализацию почти всех перечисленных подсистем. В других реализациях (DCE RPC в Windows) это не так.

См. также

Вызов удаленных процедур (RPC) Концепция удаленного вызова процедур

Идея вызова удаленных процедур (Remote Procedure Call - RPC) состоит в расширении хорошо известного и понятного механизма передачи управления и данных внутри программы, выполняющейся на одной машине, на передачу управления и данных через сеть. Средства удаленного вызова процедур предназначены для облегчения организации распределенных вычислений. Наибольшая эффективность использования RPC достигается в тех приложениях, в которых существует интерактивная связь между удаленными компонентами с небольшим временем ответов и относительно малым количеством передаваемых данных. Такие приложения называются RPC-ориентированными.

Характерными чертами вызова локальных процедур являются:

  • Асимметричность, то есть одна из взаимодействующих сторон является инициатором;
  • Синхронность, то есть выполнение вызывающей процедуры приостанавливается с момента выдачи запроса и возобновляется только после возврата из вызываемой процедуры.

Реализация удаленных вызовов существенно сложнее реализации вызовов локальных процедур. Начнем с того, что поскольку вызывающая и вызываемая процедуры выполняются на разных машинах, то они имеют разные адресные пространства, и это создает проблемы при передаче параметров и результатов, особенно если машины не идентичны. Так как RPC не может рассчитывать на разделяемую память, то это означает, что параметры RPC не должны содержать указателей на ячейки нестековой памяти и что значения параметров должны копироваться с одного компьютера на другой. Следующим отличием RPC от локального вызова является то, что он обязательно использует нижележащую систему связи, однако это не должно быть явно видно ни в определении процедур, ни в самих процедурах. Удаленность вносит дополнительные проблемы. Выполнение вызывающей программы и вызываемой локальной процедуры в одной машине реализуется в рамках единого процесса. Но в реализации RPC участвуют как минимум два процесса - по одному в каждой машине. В случае, если один из них аварийно завершится, могут возникнуть следующие ситуации: при аварии вызывающей процедуры удаленно вызванные процедуры станут «осиротевшими», а при аварийном завершении удаленных процедур станут «обездоленными родителями» вызывающие процедуры, которые будут безрезультатно ожидать ответа от удаленных процедур.

Кроме того, существует ряд проблем, связанных с неоднородностью языков программирования и операционных сред: структуры данных и структуры вызова процедур, поддерживаемые в каком-либо одном языке программирования, не поддерживаются точно так же во всех других языках.

Эти и некоторые другие проблемы решает широко распространенная технология RPC, лежащая в основе многих распределенных операционных систем. Базовые операции RPC

Чтобы понять работу RPC, рассмотрим вначале выполнение вызова локальной процедуры в обычной машине, работающей автономно. Пусть это, например, будет системный вызов

count=read (fd, buf, nbytes);

где fd - целое число, buf - массив символов, nbytes - целое число.

Чтобы осуществить вызов, вызывающая процедура заталкивает параметры в стек в обратном порядке (рисунок 3.1). После того, как вызов read выполнен, он помещает возвращаемое значение в регистр, перемещает адрес возврата и возвращает управление вызывающей процедуре, которая выбирает параметры из стека, возвращая его в исходное состояние. Заметим, что в языке С параметры могут вызываться или по ссылке (by name), или по значению (by value). По отношению к вызываемой процедуре параметры-значения являются инициализируемыми локальными переменными. Вызываемая процедура может изменить их, и это не повлияет на значение оригиналов этих переменных в вызывающей процедуре.

Если в вызываемую процедуру передается указатель на переменную, то изменение значения этой переменной вызываемой процедурой влечет изменение значения этой переменной и для вызывающей процедуры. Этот факт весьма существенен для RPC.

Существует также другой механизм передачи параметров, который не используется в языке С. Он называется call-by-copy/restore и состоит в необходимости копирования вызывающей программой переменных в стек в виде значений, а затем копирования назад после выполнения вызова поверх оригинальных значений вызывающей процедуры.

Решение о том, какой механизм передачи параметров использовать, принимается разработчиками языка. Иногда это зависит от типа передаваемых данных. В языке С, например, целые и другие скалярные данные всегда передаются по значению, а массивы - по ссылке.

Применение

Значительная часть инструментов удаленного управления операционной системой Windows (Event Viewer, Server Manager, управление печатью, списками пользователей) использует DCE RPC как средство общения по сети между управляемой службой и управляющим приложением пользовательского интерфейса. Поддержка DCE RPC присутствовала в Windows NT с самой первой версии 3.1. Клиенты DCE RPC поддерживались и в облегченной линии операционных системы Windows 3.x/95/98/Me.

Системные библиотеки Windows, предоставляющие возможности такого управления и служашие базовым уровнем для управляюших приложений пользовательского интерфейса (netapi32.dll и отчасти advapi32.dll), на деле содержат в себе клиентский код интерфейсов DCE RPC, осуществляющих это управление.

Это архитектурное решение было предметом активной критики в адрес Microsoft. Универсальные процедуры маршаллинга, присутствующие в DCE RPC, очень сложны и имеют огромный потенциал наличия дефектов, эксплуатируемых в сети путем посылки умышленно искаженного пакета DCE RPC. Значительная часть дефектов безопасности Windows, обнаруженных с конца 90-х до середины 2000-х годов, представляла собой именно ошибки в коде маршаллинга DCE RPC.

Помимо DCE RPC, в Windows активно применяется технология DCOM. Так, например, она используется как средство общения между инструментами управления веб-сервером IIS и собственно управляемым сервером. Полнофункциональный интерфейс общения с почтовой системой MS Exchange Server - MAPI - также основан на DCOM.