Чтение онлайн

на главную - закладки

Жанры

UNIX: взаимодействие процессов

Стивенс Уильям Ричард

Шрифт:

solaris % date ; client bsdi 44 tcp ; date

Wed Apr 22 14:46:57 MST 1998

timeout = 30 sec, 0 usec тайм-аут 30 секунд

bsdi: RPC: Timed out

Wed Apr 22 14:47:22 MST 1998 но прошло только 25 секунд

solaris % date ; client bsdi 55 udp ; date

Wed Apr 22 14:48:05 MST 1998

timeout = –1 sec, –1 usec ерунда какая-то

retry timeout = 15 sec, 0 usec это значение кажется правильным

bsdi: RPC: Timed out

Wed Apr 22 14:48:31 MST 1998 около 25 секунд спустя

В случае с протоколом TCP значение тайм-аута, возвращенное clnt_control, было 30 секунд, но библиотека возвратила ошибку через 25 секунд. Для протокола UDP было получено значение общего тайм-аута –1.

Чтобы понять, что тут происходит, изучим текст заглушки клиента — функции squareproc_1 в файле square_clnt.c, созданном rpcgen. Эта функция вызывает библиотечную функцию с именем clnt_call, причем последним аргументом является структура типа timeval с именем TIMEOUT, объявляемая в этом файле, и инициализируется она значением 25 секунд. Этот аргумент clnt_call отменяет значение общего тайм-аута в 30 секунд для TCP и –1 для UDP. Он используется всегда, если клиент не устанавливает общий тайм-аут явно вызовом clnt_control с запросом CLSET_TIMEOUT. Если мы хотим изменить значение общего тайм-аута, следует вызывать clnt_control, а не изменять содержимое заглушки клиента. 

ПРИМЕЧАНИЕ

Единственный способ проверить значение тайм-аута повтора для протокола UDP заключается в просмотре пакетов с помощью tcpdump. При этом можно увидеть, что первая дейтаграмма отправляется сразу после запуска клиента, а следующая — примерно 15 секунд спустя.

Управление соединением по TCP

Если мы будем наблюдать с помощью tcpdump за работой клиента и сервера из предыдущего примера, связывающихся по протоколу TCP, мы увидим, что сначала происходит установка соединения (трехэтапное рукопожатие TCP), затем отправляется запрос клиента и сервер отсылает уведомление о приеме этого запроса. Через 25 секунд после этого клиент отсылает серверу FIN, что вызвано завершением работы клиента, после чего следуют оставшиеся три этапа завершения соединения по TCP. В разделе 2.5 [24] эти этапы описаны подробно.

Мы хотим показать, что Sun RPC использует соединение по TCP следующим образом: новое соединение по TCP устанавливается при вызове clnt_create и оно используется для всех вызовов процедур, связанных с указанной программой и версией. Соединение по TCP завершается явно вызовом clnt_destroy или неявно по завершении процесса клиента:

#include <rpc/rpc.h>

void clnt_destroy(CLIENT *cl);

Начнем с клиента из листинга 16.2 и изменим его, добавив второй вызов процедуры сервера, вызовы clnt_destroy и pause. В листинге 16.10 приведен текст новой программы-клиента.

Листинг 16.10. Клиент для изучения свойств соединения по TCP

//sunrpc/square9/client.c

1 #include "unpipc.h" /* наш заголовочный файл*/

2 #include "square.h" /* создается rpcgen */

3 int

4 main(int argc, char **argv)

5 {

6 CLIENT, *cl;

7 square_in in;

8 square_out *outp;

9 if (argc != 3)

10 err_quit("usage: client <hostname> <integer-value>");

11 cl = Clnt_create(argv[1], SQUARE_PROG, SQUARE_VERS, "tcp");

12 in.arg1 = atol(argv[2]);

13 if ((outp = squareproc_1(&in, cl)) == NULL)

14 err_quit("%s", clnt_sperror(c1, argv[1]));

15 printf("result: %ld\n", outp->res1);

16 in.arg1 *= 2;

17 if ((outp = squareproc_1(&in, cl)) == NULL)

18 err_quit("%s", clnt_sperror(cl, argv[1]));

19 printf("result: %ld\n", outp->res1);

20 clnt_destroy(cl);

21 pause;

22 exit(0);

23 }

После запуска получим ожидаемый результат:

solaris % client kalae 5

result: 25

result: 100

программа в состоянии ожидания, пока мы не завершим ее вручную

Однако проверить наши предыдущие утверждения можно лишь с помощью результатов работы программы tcpdump. Она показывает, что создается одно соединение по TCP (вызовом clnt_create) и оно используется для обоих запросов клиента. Соединение завершается вызовом clnt_destroy, хотя клиент при этом и не завершает свою работу.

Идентификатор транзакций

Другая часть стратегии тайм-аутов и повторных передач заключается в использовании идентификаторов транзакций (transaction ID или XID) для распознавания запросов клиента и ответов сервера. Когда клиент вызывает функцию RPC, библиотека присваивает этому вызову 32-разрядный целочисленный номер и это значение отсылается в запросе RPC. Сервер должен добавить к своему ответу этот номер. При повторной отсылке запроса идентификатор не меняется. Служит он двум целям:

1. Клиент проверяет, что XID ответа совпадает с XID запроса. Если совпадения нет, ответ игнорируется. Если используется протокол TCP, у клиента практически нет шансов получить ответ с неправильным идентификатором, но при использовании протокола UDP поверх плохой сети вероятность получения неправильного XID достаточно высока.

2. Серверу разрешается помещать отсылаемые ответы в кэш, и для проверки идентичности ответов используется, в частности, именно XID. Об этом мы вскоре расскажем.

Пакет TI-RPC использует определенный алгоритм вычисления XID для нового запроса. Алгоритм этот описан ниже. Значок ^ означает побитовую операцию XOR (исключающее ИЛИ):

struct timeval now;

gettimeofday(&now, NULL);

xid = getpid ^ now.tv_sec ^ now.tv_usec;

Кэш повторных ответов

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

Поделиться:
Популярные книги

Старый, но крепкий 4

Крынов Макс
4. Культивация без насилия
Фантастика:
уся
фэнтези
5.00
рейтинг книги
Старый, но крепкий 4

Пышка (сборник)

Де Мопассан Ги
Проза:
классическая проза
8.45
рейтинг книги
Пышка (сборник)

Форма жизни

Драу Михаэль
Фантастика:
боевая фантастика
киберпанк
7.62
рейтинг книги
Форма жизни

Закрытые Миры

Муравьёв Константин Николаевич
Вселенная EVE Online
Фантастика:
фэнтези
5.86
рейтинг книги
Закрытые Миры

Эмиссар

Листратов Валерий
8. Ушедший Род
Фантастика:
боевая фантастика
аниме
попаданцы
7.50
рейтинг книги
Эмиссар

Кодекс Крови. Книга II

Борзых М.
2. РОС: Кодекс Крови
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Кодекс Крови. Книга II

Тринадцатый VI

NikL
6. Видящий смерть
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Тринадцатый VI

Наследие Маозари 6

Панежин Евгений
6. Наследие Маозари
Фантастика:
попаданцы
постапокалипсис
рпг
фэнтези
эпическая фантастика
5.50
рейтинг книги
Наследие Маозари 6

Я еще граф. Книга #8

Дрейк Сириус
8. Дорогой барон!
Фантастика:
боевая фантастика
попаданцы
5.00
рейтинг книги
Я еще граф. Книга #8

Развод в 45. От любви до ненависти

Гофман Крис
6. Развод
Любовные романы:
остросюжетные любовные романы
5.40
рейтинг книги
Развод в 45. От любви до ненависти

Кодекс Охотника. Книга II

Винокуров Юрий
2. Кодекс Охотника
Фантастика:
фэнтези
попаданцы
боевая фантастика
юмористическое фэнтези
5.00
рейтинг книги
Кодекс Охотника. Книга II

Контрольный поцелуй

Донцова Дарья
8. Любительница частного сыска Даша Васильева
Детективы:
иронические детективы
9.15
рейтинг книги
Контрольный поцелуй

Неучтенный элемент. Том 10

NikL
10. Антимаг. Вне системы
Фантастика:
фэнтези
5.00
рейтинг книги
Неучтенный элемент. Том 10

Полонянин

Гончаров Олег
2. Ночь Сварога
Приключения:
исторические приключения
8.30
рейтинг книги
Полонянин