Литмир - Электронная Библиотека
Содержание  
A
A

 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 представлена последняя разработанная нами версия).

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

Теперь мы перепишем наши клиент и сервер UDP из разделов 8.3 и 8.5 с использованием сокетов. В листинге 15.5 показан сервер, который является модификацией листинга 8.1.

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

//unixdomain/unixdgserv01.c

 1 #include "unp.h"

 2 int

 3 main(int argc, char **argv)

 4 {

 5  int sockfd;

 6  struct sockaddr_un servaddr, cliaddr;

 7  sockfd = Socket(AF_LOCAL, SOCK_DGRAM, 0);

 8  unlink(UNIXDG_PATH);

 9  bzero(&servaddr, sizeof(servaddr));

10  servaddr.sun_family = AF_LOCAL;

11  strcpy(servaddr.sun_path, UNIXDG_PATH);

12  Bind(sockfd, (SA*)&servaddr, sizeof(servaddr));

13  dg_echo(sockfd, (SA*)&cliaddr, sizeof(cliaddr));

14 }

6
 Две структуры адреса сокета относятся теперь к типу
sockaddr_un
.

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

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

13
 Используется та же функция
dg_echo
(см. листинг 8.2).

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

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

//unixdomain/unixdgcli01.с

 1 #include "unp.h"

 2 int

 3 main(int argc, char **argv)

 4 {

 5  int sockfd;

 6  struct sockaddr_un cliaddr, servaddr;

 7  sockfd = Socket(AF_LOCAL, SOCK_DGRAM, 0);

 8  bzero(&cliaddr, sizeof(cliaddr)); /* связывание сокета с адресом */

 9  cliaddr.sun_family = AF_LOCAL;

10  strcpy(cliaddr.sun_path, tmpnam(NULL);

11  Bind(sockfd, (SA*)&cliaddr, sizeof(cliaddr));

12  bzero(&servaddr, sizeof(servaddr)); /* заполняем структуру адреса

                                           сокета сервера */

13  servaddr.sun_family = AF_LOCAL;

14  strcpy(servaddr.sun_path, UNIXDG_PATH);

15  dg_cli(stdin, sockfd, (SA*)&servaddr, sizeof(servaddr));

16  exit(0);

17 }

6
 Структурой адреса сокета, содержащей адрес сервера, теперь будет структура
sockaddr_un
. Мы также размещаем в памяти одну из этих структур, чтобы она содержала адрес клиента, о чем мы расскажем далее.

7
 Первый аргумент функции
socket
— это
AF_LOCAL
.

8-11
 В отличие от клиента UDP при использовании дейтаграммного доменного протокола Unix требуется явно связать с помощью функции
bind
полное имя с нашим сокетом, чтобы сервер имел полное имя, на которое он мог бы отправить свой ответ. Мы вызываем функцию
tmpnam
, чтобы получить уникальное полное имя, с которым затем при помощи функции
bind
свяжем наш сокет. Вспомните из раздела 15.4, что при отправке дейтаграммы на неприсоединенный дейтаграммный доменный сокет Unix не происходит неявного связывания полного имени с сокетом. Следовательно, если мы опустим этот шаг, вызов сервером функции
recvfrom
в функции
dg_echo
возвращает пустое полное имя, что затем приведет к ошибке, когда сервер вызовет функцию
sendto
.

170
{"b":"225366","o":1}