Главная страница  Взаимодействие нетривиальных процессов 

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 [ 148 ] 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186

Присваивание значений

12- 1В Для присваиваения значения объединению мы устанавливаем дискриминант в TRUE, а затем присваиваем значение полю 1 ong. Длину массива мы также сначала устанавливаем в 1. Указатель мы устанавливаем на соответствующее значение в памяти.

При запуске этой программы мы получим ожидаемые щесть 4-байтовых значений:

Solaris % optl

1 значение дискриминанта TRUE

1 длина массива переменной длины

9В76

1 флаг для ненулевого указателя

Пример: обработка связного списка

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

Листинг 16.21. Спецификация XDR для связного списка пар имя-значение

sunrpc/xdrl/opt2.x

1 struct myllst {

2 string name<>;

3 long value:

4 mylist *next:

5 }:

6 struct args {

7 myllst *llst:

8 }:

1 - 5 Структура щу 1 i St содержит одну пару имя-значение и указатель на следующую структуру такого типа. Указатель в последней структуре списка будет нулевым.

В листинге 16.22 приведен текст заголовочного файла, созданного программой rpcgen из файла opt2. х.

Листинг 16.22. Заголовочный файл, созданный программой rpcgen

sunrpc/xdrl/opt2.h

7 struct mylist {

8 char *name;

9 long value:

10 struct mylist *next:

11 }:

12 typedef struct itiyllst myllst:

13 struct args {

14 itiylist *l1st:

15 }:

16 typedef struct args args:



В листинге 16.23 приведен текст программы, инициализирующей связный список с тремя парами имя-значение и кодирующей его с помощью библиотеки XDR.

Листинг 16.23. Инициализация, кодирование связного списка и вывод результата

sunrpc/xdrl/opt2.c

#1nclude unpipc.h

#1nclude opt2.h

maindnt argc. char **argv)

int 1:

XDR xhandle:

long *lptr:

args out:

/* структура, которую мы

char *buff:

/* результат кодирования

mylist nameval[4]:

/* до четырех элементов i

size t size:

out.list = &nameval[2]:

/* [2] -> [1] -> [0] */

nameval[2].name = namel :

nameval[2].value = 0x1111;

nameval[2].next = &nameval[l]

nameval[l].name = namee2 ;

nameval[l].value = 0x2222:

nameval[l].next = &nameval[0]

nameval[0].name = патеееЗ ;

namevaUO], value = 0x3333:

nameval[0].next = NULL:

buff = Malloc(BUFFSIZE): /* адрес должен быть кратен 4

xdrmem create(&xhandle. buff.

BUFFSIZE. XDRJNCODE):

if (xdr args(&xhandle. &out)

!= TRUE)

err quit( xdr args error );

size = xdr getpos(&xhandle);

Iptr = (long *) buff:

for (i = 0; i < size; i += 4)

printf( XBlx\n . (long) ntohl(*lptr++)):

exit(O):

Инициализация связного списка

11-22 Мы выделяем память под четыре элемента, но инициализируем только три из них. Первая запись nameval [2], потом nameval [1] и nameval [0]. Указатель на начало списка (out. 1 ist) устанавливается на &nameval [2]. Мы инициализируем список в таком порядке, чтобы показать, что библиотека XDR обрабатывает указатели и порядок в списке оказывается именно таким, каким он был в нащей программе, и не зависит от того, какие массивы для этого используются. Мы также инициализируем значения элементов списка щестнадцатеричными величинами, поскольку будем выводить их в этом формате.



Вывод программы показывает, что перед каждым элементом списка идет значение 1 в 4 байтах (что мы можем считать длиной массива переменной длины с одним элементом или булевским значением TRUE). Четвертая запись состоит из 4 байт, в которых записан 0. Она обозначает конец списка:

Solaris % opt2

1 дальше идет один элемент

5 длина строки 6e616d65 имя (пате)

31000000 1 и три байта дополнения

1111 значение

1 один элемент

6 длина строки 6e616d65 имя

65320000 е 2 и 2 байта дополнения

2222 значение

1 один элемент

1 длина строки

6e616d65 имя

65653300 е е 3 и 1 байт дополнения

3333 значение

О конец слиска

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

16.9. Форматы пакетов RPC

На рис. 16.5 приведен формат запроса RPC в пакете TCP.

Поскольку TCP передает поток байтов и не предусматривает границ сообщений, приложение должно предусматривать способ разграничения сообщений. Sun RPC определяет запись как запрос или ответ, и каждая запись состоит из одного или более фрагментов. Каждый фрагмент начинается с 4-байтового значения: старщий бит является флагом последнего фрагмента, а следующие 31 бит представляют собой счетчик (длина фрагмента). Если бит последнего фрагмента имеет значение О, данный фрагмент не является последним в записи.

ПРИМЕЧАНИЕ -

Это 4-байтовое значение передается в порядке big-endian, так же как и 4-байтовые целые в XDR, но оно не относится к стандарту XDR, поскольку он не предусматривает передачи битовых полей.

Если вместо TCP используется UDP, первое поле в заголовке UDP будет идентификатором транзакции (XID), как показано на рис. 16.7.

ПРИМЕЧАНИЕ -

При использовании TCP на размер запроса и ответа RPC ограничения не накладываются, поскольку может использоваться любое количество фрагментов, а длина каждого из них задается 31-разрядным целым. Но при использовании протокола UDP запрос (и ответ) должен помещаться в дейтаграмму целиком, а максимальное количество данных в ней - 65 507 байт (для IPv4). Во многих реализациях, предшествовавших TI-RPC, размер ограничивался значением около 8192 байт, поэтому если требуется передавать более 8000 байт, следует пользоваться протоколом TCP.



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 [ 148 ] 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186

© 2000 - 2024 ULTRASONEX-AMFODENT.RU.
Копирование материалов разрешено исключительно при условии цититирования.