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

We use cookies. Read the Privacy and Cookie Policy

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 Первый аргумент функции socket — AF_LOCAL.

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

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

Данный текст является ознакомительным фрагментом.