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

15.5. Клиент и сервер потокового доменного протокола Unix

15.5. Клиент и сервер потокового доменного протокола Unix

Теперь мы перепишем наш эхо-клиент и эхо-сервер TCP из главы 5 с использованием доменных сокетов Unix. В листинге 15.3 показан сервер, который является модификацией сервера из листинга 5.9 и использует потоковый доменный протокол Unix вместо протокола TCP.

Листинг 15.3. Эхо-сервер потокового доменного протокола Unix

//unixdomain/unixstrserv01.c
 1 #include "unp.h"
 2 int
 3 main(int argc, char **argv)
 4 {
 5  int listenfd, connfd;
 6  pid_t childpid;
 7  socklen_t clilen;
 8  struct sockaddr_un cliaddr, servaddr;
 9  void sig_chld(int);
10  listenfd = Socket(AF_LOCAL, SOCK_STREAM, 0);
11  unlink(UNIXSTR_PATH);
12  bzero(&servaddr, sizeof(servaddr));
13  servaddr.sun_family = AF_LOCAL;
14  strcpy(servaddr.sun_path, UNIXSTR_PATH);
15  Bind(listenfd, (SA*)&servaddr, sizeof(servaddr));
16  Listen(listenfd, LISTENQ);
17  Signal(SIGCHLD, sig_chld);
18  for (;;) {
19   clilen = sizeof(cliaddr);
20   if ((connfd = accept(listenfd, (SA*)&cliaddr, &clilen)) < 0) {
21    if (errno == EINTR)
22     continue; /* назад в for() */
23    else
24     err_sys("accept error");
25   }
26   if ((childpid = Fork()) == 0) { /* дочерний процесс */
27    Close(listenfd); /* закрывается прослушиваемый сокет */
28    str_echo(connfd); /* обработка запроса */
29    exit(0);
30   }
31   Close(connfd); /* родитель закрывает присоединенный сокет */
32  }
33 }
8
 Теперь две структуры адреса сокета относятся к типу sockaddr_un.

10 Для создания потокового доменного сокета Unix первый аргумент функции socket должен иметь значение AF_LOCAL.

11-15 Константа UNIXSTR_PATH определяется в файле unp.h как /tmp/unix/str. Сначала мы вызываем функцию unlink, чтобы удалить полное имя в случае, если оно сохранилось после предыдущего запуска сервера, а затем инициализируем структуру адреса сокета перед вызовом функции bind. Ошибка при выполнении функции unlink не является аварийной ситуацией.

Обратите внимание, что этот вызов функции bind отличается от вызова, показанного в листинге 15.2. Здесь мы задаем размер структуры адреса сокета (третий аргумент) как общий размер структуры sockaddr_un, а не просто число байтов, занимаемое полным именем. Оба значения длины приемлемы, поскольку полное имя должно оканчиваться нулем.

Оставшаяся часть функции такая же, как и в листинге 5.9. Используется та же функция str_echo (см. листинг 5.2).

В листинге 15.4 представлен эхо-клиент потокового доменного протокола Unix. Это модификация листинга 5.3.

Листинг 15.4. Эхо-клиент потокового доменного протокола Unix

//unixdomain/umxstrcli01.c
 1 #include "unp.h"
 2 int
 3 main(int argc, char **argv)
 4 {
 5  int sockfd;
 6  struct sockaddr_un servaddr;
 7  sockfd = Socket(AF_LOCAL, SOCK_STREAM, 0);
 8  bzero(&servaddr, sizeof(servaddr));
 9  servaddr sun_family = AF_LOCAL;
10  strcpy(servaddr.sun_path, UNIXSTR_PATH);
11  Connect(sockfd, (SA*)&servaddr, sizeof(servaddr));
12  str_cli(stdin, sockfd); /* выполняет всю работу */
13  exit(0);
14 }
6
 Теперь структурой адреса сокета, которая должна содержать адрес сервера, будет структура sockaddr_un.

7 Первый аргумент функции socketAF_LOCAL.

8-10 Код для заполнения структуры адреса сокета идентичен коду, показанному для сервера: инициализация структуры нулем, установка семейства протоколов AF_LOCAL и копирование полного имени в элемент sun_path.

12 Функция str_cli — та же, что и раньше (в листинге 6.2 представлена последняя разработанная нами версия).

Оглавление книги


Генерация: 1.237. Запросов К БД/Cache: 3 / 1
поделиться
Вверх Вниз