Уильям Стивенс - UNIX: разработка сетевых приложений

Тут можно читать онлайн Уильям Стивенс - UNIX: разработка сетевых приложений - бесплатно ознакомительный отрывок. Жанр: comp-osnet, издательство Питер, год 2007. Здесь Вы можете читать ознакомительный отрывок из книги онлайн без регистрации и SMS на сайте лучшей интернет библиотеки ЛибКинг или прочесть краткое содержание (суть), предисловие и аннотацию. Так же сможете купить и скачать торрент в электронном формате fb2, найти и слушать аудиокнигу на русском языке или узнать сколько частей в серии и всего страниц в публикации. Читателям доступно смотреть обложку, картинки, описание и отзывы (комментарии) о произведении.
  • Название:
    UNIX: разработка сетевых приложений
  • Автор:
  • Жанр:
  • Издательство:
    Питер
  • Год:
    2007
  • Город:
    Санкт-Петербург
  • ISBN:
    5-94723-991-4
  • Рейтинг:
    4.33/5. Голосов: 91
  • Избранное:
    Добавить в избранное
  • Отзывы:
  • Ваша оценка:
    • 80
    • 1
    • 2
    • 3
    • 4
    • 5

Уильям Стивенс - UNIX: разработка сетевых приложений краткое содержание

UNIX: разработка сетевых приложений - описание и краткое содержание, автор Уильям Стивенс, читайте бесплатно онлайн на сайте электронной библиотеки LibKing.Ru

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

UNIX: разработка сетевых приложений - читать онлайн бесплатно ознакомительный отрывок

UNIX: разработка сетевых приложений - читать книгу онлайн бесплатно (ознакомительный отрывок), автор Уильям Стивенс
Тёмная тема
Сбросить

Интервал:

Закладка:

Сделать

В разделе 28.7 мы приводим пример передачи дескриптора, в котором участвуют неродственные (unrelated) процессы, а в разделе 30.9 — пример, где задействованы родственные процессы. В них мы будем использовать функции read_fdи write_fd, которые только что описали.

15.8. Получение информации об отправителе

На рис. 14.4 мы показали другой тип информации, передаваемой через доменный сокет Unix в виде вспомогательных данных: информацию об отправителе, которая передается с помощью структуры cmsgcred, определяемой путем включения заголовочного файла . Упаковка и формат данных зависят от операционной системы. Такая возможность появилась только в BSD/OS 2.1. Мы описываем FreeBSD, а прочие варианты Unix во многом подобны ей (проблема обычно состоит в выборе структуры, которую следует использовать для передачи данных). Рассказ об этой возможности мы считаем необходимым, поскольку это важное, хотя и простое дополнение доменных протоколов Unix. Когда клиент и сервер связываются с помощью этих протоколов, серверу часто бывает необходим способ точно узнать, кто является клиентом, чтобы убедиться, что клиент имеет право запрашивать определенный сервис.

struct fcred {

uid_t fc_ruid; /* действующий идентификатор пользователя */

gid_t fc_rgid; /* действующий групповой идентификатор */

char fc_login[MAXLOGNAME]; /* имя setlogin() */

uid_t fc_uid; /* идентификатор пользователя */

short fc_ngroups; /* количество групп */

gid_t fc_groups[NGROUPS]; /* дополнительные групповые идентификаторы */

};

#define fc_gid fc_groups[0] /* групповой идентификатор */

Обычно MAXLONGNAMEи NGROUPSимеют значение 16. Значение fc_ngroupsравно как минимум 1, а первым элементом массива является идентификатор группы.

Эта информация всегда доступна через доменный сокет Unix, хотя отправителю часто приходится принимать дополнительные меры для обеспечения ее отправки вместе с данными, и получателю также приходится выполнять некоторые действия (например, устанавливать параметры сокета). В системе FreeBSD получатель может обойтись вызовом recvmsgс достаточно большим буфером для вспомогательных данных, чтобы туда поместились идентифицирующие данные (листинг 15.12). Однако отправитель обязан включить структуру cmsgcredпри отправке данных посредством sendmsg. Хотя включение структуры осуществляется отправителем, заполняется она ядром. Благодаря этому передача идентифицирующих данных через доменный сокет Unix является надежным способом проверки клиента.

Пример

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

Листинг 15.12. Функция read_cred: чтение и возвращение идентифицирующих данных отправителя

//unixdomain/readcred.c

1 #include "unp.h"

2 #define CONTROL_LEN (sizeof(struct cmsghdr) + sizeof(struct cmsgcred))

3 ssize_t

4 read_cred(int fd, void *ptr, size_t nbytes, struct cmsgcred *cmsgcredptr)

5 {

6 struct msghdr msg;

7 struct iovec iov[1];

8 char control[CONTROL_LEN];

9 int n;

10 msg.msg_name = NULL;

11 msg.msg_namelen = 0;

12 iov[0].iov_base = ptr;

13 iov[0].iov_len = nbytes;

14 msg.msg_iov = iov;

15 msg.msg_iovlen = 1;

16 msg.msg_control = control;

17 msg.msg_controllen = sizeof(control);

18 msg.msg_flags = 0;

19 if ((n = recvmsg(fd, &msg, 0)) < 0)

20 return(n);

21 cmsgcredptr->cmcred_ngroups = 0; /* идентифицирующие данные не получены */

22 if (cmsgcredptr && msg.msg_controllen > 0) {

23 struct cmsghdr *cmptr = (struct cmsghdr*)control;

24 if (cmptr->cmsg_len < CONTROL_LEN)

25 err_quit("control length = %d", cmptr->cmsg_len);

26 if (cmptr->cmsg_level != SOL_SOCKET)

27 err_quit("control level != SOL_SOCKET");

28 if (cmptr->cmsg_type != SCM_CREDS)

29 err_quit("control type != SCM_CREDS");

30 memcpy(cmsgcredptr, CMSG_DATA(cmptr), sizeof(struct cmsgcred));

31 }

32 return(n);

33 }

3-4 Первые три аргумента идентичны аргументам функции read, а четвертый аргумент — это указатель на структуру cmsgcred, которая будет заполнена.

22-31 Если данные были переданы, проверяются длина, уровень и тип вспомогательных данных, и результирующая структура копируется обратно вызывающему процессу. Если никаких идентифицирующих данных не было передано, мы обнуляем структуру. Поскольку число групп ( cmcred_ngroups) всегда равно 1 или больше, нулевое значение указывает вызывающему процессу, что ядро не возвратило никаких идентифицирующих данных.

Функция mainдля нашего эхо-сервера (см. листинг 15.3) остается неизменной. В листинге 15.13 показана новая версия функции str_echo, полученная путем модификации листинга 5.2. Эта функция вызывается дочерним процессом после того, как родительский процесс принял новое клиентское соединение и вызвал функцию fork.

Листинг 15.13. Функция str_echo, запрашивающая идентифицирующие данные клиента

//unixdomain/strecho.c

1 #include "unp.h"

2 ssize_t read_cred(int, void*, size_t, struct cmsgcred*);

3 void

4 str_echo(int sockfd)

5 {

6 ssize_t n;

7 int i;

8 char buf[MAXLINE];

9 struct cmsgcred cred;

10 again:

11 while ((n = read_cred(sockfd, buf, MAXLINE, &cred)) > 0) {

12 if (cred.cmcred_ngroups == 0) {

13 printf("(no credentials returned)\n");

14 } else {

15 printf("PID of sender = %d\n", cred.cmcred_pid);

16 printf("real user ID = %d\n", cred.cmcred_uid);

17 printf("real group ID = %d\n", cred.cmcred_gid);

18 printf("effective user ID = %d\n", cred.cmcred_euid);

19 printf("%d groups:", cred.cmcred_ngroups - 1);

20 for (i = 1; i < cred.cmcred_ngroups; i++)

21 printf(" %d", cred.cmcred_groups[i]);

22 printf("\n");

23 }

24 Writen(sockfd, buf, n);

25 }

26 if (n < 0 && errno == EINTR)

27 goto again;

28 else if (n < 0)

29 err_sys("str_echo: read error");

30 }

11-23 Если идентифицирующие данные возвращаются, они выводятся.

24-25 Оставшаяся часть цикла не меняется. Этот код считывает строки от клиента и затем отправляет их обратно клиенту.

Наш клиент, представленный в листинге 15.4, остается практически неизменным. Мы добавляем передачу пустой структуры cmsgcredпри вызове sendmsg, которая заполняется ядром.

Перед запуском клиента определим свои личные данные командой id:

freebsd % id

uid=1007(andy) gid=1007(andy) groups=1007(andy), 0(wheel)

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

freebsd % unixstrserv02

PID of sender = 26881

real user ID = 1007

real group ID = 1007

effective user ID = 1007

2 groups: 1007 0

Информация выводится только после отправки клиентом данных серверу. Мы видим, что сведения соответствуют тем, которые были получены командой id.

Читать дальше
Тёмная тема
Сбросить

Интервал:

Закладка:

Сделать


Уильям Стивенс читать все книги автора по порядку

Уильям Стивенс - все книги автора в одном месте читать по порядку полные версии на сайте онлайн библиотеки LibKing.




UNIX: разработка сетевых приложений отзывы


Отзывы читателей о книге UNIX: разработка сетевых приложений, автор: Уильям Стивенс. Читайте комментарии и мнения людей о произведении.


Понравилась книга? Поделитесь впечатлениями - оставьте Ваш отзыв или расскажите друзьям

Напишите свой комментарий
x