- •Министерство общего и профессионального о образовании рф
- •Санкт-Петербургский государственный электротехнический
- •Университет (лэти)
- •Взаимодействие сетевых приложений
- •Введение
- •1.2. Операции с сокетом
- •Int socket(int family, int type, int protocol).
- •Int bind(int fd, struct sockaddr *umyaddr, int addrlen),
- •Int uname(struct utsname * buf);
- •Int getpeername(int fd, struct sockaddr * umyaddr, int * usockaddr_len),
- •Int listen(int fd, int acklog),
- •Int write(int fd, char*ubuf, int len);
- •Int send(int fd, void * buff, int len, unsigned flags);
- •Int sendto(int fd, void * buff, int len, unsigned flags, struct sockaddr*addr, int addr_len);
- •Int read(int fd, char *ubuf, int size);
- •Int recv(int fd, void * buff, int len, unsigned flags);
- •Int recvfrom(int fd, void * buff, int len, unsigned flags, struct sockaddr * addr, int * addr_len).
- •Int select(int numfds, fd_set * readfds, fd_set*writefds, fd_set*exeptfds, struct timeval*timeout).
- •Int id_socket, res_select;
- •1.4 Задания к лабораторной работе 1
- •Лабораторная работа 2 построение серверных и клиентских программ с использованием компилятора rpcgen
- •2.1. Описание интерфейса удаленной процедуры
- •Void main (int argc, char* argv[])
- •Int имя_функции (caddr_t resp, struct sockaddr_in * server_addr);
- •Int prtnt_result(caddr_t out, struct sockaddr_in *s)
- •Void main( )
- •197376, С.-Петербург, ул. Проф. Попова, 5
Void main (int argc, char* argv[])
{
char ** pdale_ time;
CLIENT* pclient;
if (! ( pclient=clnt_create (argv[l], CURRENT_TIMEPROG, CURRENT_TIMEVER, “udp”)))
clnt_pcreateerror ("Нет связи с сервером ");
else /* вызов заглушки клиента */.
if (! ( pdate_time=current_time_1(NULL, pclient)))
clnt_perror ("Процедура не выполнена");
else printf ("Местное время и дата: %s\n”, *pdate_time);
}
Для получения загрузочного модуля клиентской программы нужно ее оттранслировать вместе с модулем заглушки клиента. Вызов компилятора для трансляции будет таким:
gcc-o сr_client cr_client.c current_time_clnt.c
Если удаленная процедура CURRENT_TIME была запушена на машине с именем owl, то клиентская программа может быть запущена на любой другой машине, соединенной с машиной owl локальной или глобальной сетью. Командная строчка для запуска клиентской программы будет иметь следующий вид:
cr_client owl
2.5. Широковещательный запрос клиента
Широковещательный запрос - это запрос ко всем машинам, подключенным к сети, на выполнение удаленной процедуры. Он используется, если клиент не знает, на какой машине установлена удаленная процедура, или когда процедура установлена на нескольких машинах и клиент хочет получить результаты выполнения от всех или некоторых запущенных, процедур. Широковещательный запрос реализуется по протоколу udp и не требует предварительной установки соединения c сервером. Поэтому для выполнения запроса не нужен модуль заглушки клиента. Для выполнения широковещательного запроса клиент должен обратиться к системной функции clnt_broadcast. Она имеет следующее описание:
enum clnt_stat clht_broadcast(u_long prognum, u_long versnum, n_long funcnum, xdrproc_t argfunc, char* argp, xdproc_t resfunc, char* resp, resultproc_t callme);
-27-
Параметры prognum, versnum и funcnum - это соответственно номера программы, версии и процедуры, которые определены при описании интерфейса и указывают, к какой удаленной процедуре адресован широковещательный запрос. В параметрах argfunc и resfunc задаются имена XDR-функций, используемых для преобразования входного аргумента и возвращаемого значения удаленной процедуры. Адреса аргумента и возвращаемого значения указываются соответственно в параметрах argp и resp. Параметр callme - это имя обслуживающей функции, которая определяется клиентом и вызывается при каждом ответе одного из серверов. Функция clnt_broadcast возвращает значение в виде констант перечислимого типа. Например:
RPC_SUCCESS - ответ от сервера принят;
RPC_TIMEDOUT - ни один сервер не ответил на запрос;
RPC_CANTENCODEARGS - ошибка при XDR-преобразовании аргумента;
RPC_CANTDECODERES - ошибка при XDR-преобразовании результата ;
RPC_CANTSEND - ошибка при посылке вызова;
RPC_CANTRECV - ошибка при приеме ответа.
Остальные константы, определенные в перечислимом типе, указывают на ту или иную ошибку при передаче широковещательного вызова или приеме ответов от серверов. Весь перечень констант имеется в файле rpc/clnt.h.
Широковещательный запрос позволяет обратиться только к удаленной процедуре с одним аргументом. Если процедуре требуется передать несколько аргументов, то они должны быть упакованы в одну структуру и переданы ей как один параметр. Перед посылкой по сети аргумент и возвращаемое значение необходимо сначала преобразовать в формат XDR. Это преобразование выполняется с помощью базовых или сгенерированных компилятором rpcgen XDR- функций. В таблице перечислены базовые XDR-функции для встроенных типов данных.
Тип данных |
XDR-функция |
Пояснения |
int |
xdr_int |
Целый со знаком |
long |
xdr_long |
Длинный целый со знаком |
short |
xdr_short |
Короткий целый со знаком |
char |
xdr_char |
Символьный(один байт со знаком) |
u_int |
xdr_u_int |
Беззнаковый целый |
u_long |
xdr_u_long |
Беззнаковый длинный |
u_short |
xdr_u_short |
Беззнаковый короткий |
u_char |
xdr_u_char |
Беззнаковый символьный(один байт) |
-28-
Окончание таблицы
Тип данных |
XDR-функция |
Пояснения |
float |
xdr_float |
Вещественный |
double |
xdr_double |
Вещественным двойной точности |
enum |
xdr_enum |
Перечислимый |
bool |
xdr_bool |
Булевский (TRUE. FALSE) |
string |
xdr_string |
Строковый |
union |
xdr_union |
Объединенный |
void |
xdr_void |
Отсутствие значения |
Все XDR-функции возвращают значение TRUE, если преобразование выполнено успешно, и FALSE - в противном случае. Если при описании интерфейса пользователь определил собственные типы данных, то rpcgen-компилятор сгенерирует для них XDR-функции и поместит их в файл с расширением xdr. Этот файл нужно компилировать вместе с клиентской программой.
Функция clnt_broadcast посылает запрос всем узлам сети и в течение 4 с ожидает поступления ответов. Если неполучено ни одного ответа, выполняется повторный запрос с увеличением времени ожидания на 2 с. Такое повторение запросов осуществляется 5 раз, после чего функция clnt_broadcast завершает свою работу и возвращает значение RPC_TlMEDOUT. Если пришел один ими несколько ответов, то для каждого ответа вызывается обслуживающая функция, имя которой задано в аргументе callme. Прототип обслуживающей функции должен быть таким: