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

ЖАНРЫ

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

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

Шрифт:

14 struct args {

15 optlong arg1;

16 struct {

17 u_int arg2_len;

18 long *arg2_val;

19 } arg2;

20 long *arg3;

21 };

22 typedef struct args args;

14-21 Хотя все три аргумента кодируются одинаково, способы присваивания и получения их значений в языке С различны.

В листинге 16.19 приведен текст простой пpoгрaммы, устанавливающей

значения всех трех аргументов так, что ни одно из полей long не кодируется.

Листинг 16.19. Ни одно из значений не будет закодировано

//sunrpc/xdr1/opt1z.с

1 #include "unpipc.h"

2 #include "opt1.h"

3 int

4 main(int argc, char **argv)

5 {

6 int i;

7 XDR xhandle;

8 char *buff;

9 long *lptr;

10 args out;

11 size_t size;

12 out.arg1.flag = FALSE;

13 out.arg2.arg2_len = 0;

14 out.arg3 = NULL;

15 buff = Malloc(BUFFSIZE); /* Адрес должен быть кратен четырем */

16 xdrmem_create(&xhandle, buff, BUFFSIZE, XOR_ENCODE);

17 if (xdr_args(&xhandle, &out) != TRUE)

18 err_quit("xdr_args error");

19 size = xdr_getpos(&xhandle);

20 lptr = (long*)buff;

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

22 printf("%ld\n", (long) ntohl(*lptr++));

23 exit(0);

24 }

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

12-14 Дискриминанту объединения присваивается значение FALSE, длина массива переменной длины устанавливается в 0, а указатель делается нулевым (NULL).

Выделение буфера и кодирование

15-19 Мы выделяем буфер и кодируем структуру out в поток XDR. 

Вывод содержимого буфера XDR

20-22 Мы выводим содержимое буфера XDR по 4 байта, используя функцию ntohl (host-to-network long integer) для преобразования из порядка XDR big-endian в байтовый порядок узла. В результате получается именно то, что должно было быть помещено в буфер библиотекой XDR времени выполнения:

solaris % opt1z

0

0

0

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

В листинге 16.20 приведена измененная версия программы, которая присваивает значения всем трем аргументам, кодирует их в поток XDR и выводит его содержимое.

Листинг 16.20. Присваивание значений аргументам из листинга 16.17

//sunrpc/xdr1/opt1.c

1 #include "unpipc.h"

2 #include "opt1.h"

3 int

4 main(int argc, char **argv)

5 {

6 int i;

7 XOR xhandle;

8 char *buff;

9 long lval2, lval3, *lptr;

10 args out;

11 size_t size;

12 out.arg1.flag = TRUE;

13 out.arg1.optlong_u.val = 5;

14 lval2 = 9876;

15 out.arg2.arg2_len = 1;

16 out.arg2.arg2_val = &lval2;

17 lval3 = 123;

18 out.arg3 = &lval3;

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

20 xdrmem_create(&xhandle, buff, BUFFSIZE, XDR_ENCODE);

21 if (xdr_args(&xhandle, &out) != TRUE)

22 err_quit("xdr_args error");

23 size = xdr_getpos(&xhandle);

24 lptr = (long *) buff;

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

26 printf("%ld\n", (long) ntohl(*lptr++));

27 exit(0);

28 }

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

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

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

solaris % opt1

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

5

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

9876

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

123

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

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

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

//sunrpc/xdr1/opt2.x

1 struct mylist {

2 string name<>;

3 long value;

4 mylist *next;

5 };

6 struct args {

7 mylist *list;

8 };

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

Поделиться с друзьями: