Шрифт:
Отправка ответа
35-38
Сервер отсылает сообщения, используя идентификатор протокола, флаги и номер потока (который, возможно, был увеличен), хранящиеся в структуре sri
. Заметьте, что нашему серверу не нужны уведомления об установке ассоциаций, поэтому он отключает все события, которые привели бы к передаче сообщений в буфер сокета. Сервер полагается на сведения из структуры
sctp_sndrcvinfo
, а обратный адрес берет из переменной cliaddr
. Этого оказывается достаточно для отправки эхо-ответа собеседнику через установленную им ассоциацию. Программа работает до тех пор, пока пользователь не завершит ее передачей сигнала.
10.3. Потоковый эхо-клиент SCTP типа «один-ко-многим»: функция main
В листинге 10.2 приведена функция
main
нашего клиента SCTP. Листинг 10.2. Потоковый эхо-клиент SCTP
//sctp/sctpclient01.c
1 #include "unp.h"
2 int
3 main(int argc, char **argv)
4 {
5 int sock_fd;
6 struct sockaddr_in servaddr;
7 struct sctp_event_subscribe evnts;
8 int echo_to_all=0;
9 if (argc < 2)
10 err_quit("Missing host argument - use '%s host [echo]'\n", argv[0]);
11 if (argc > 2) {
12 printf("Echoing messages to all streams\n");
13 echo_to_all = 1;
14 }
15 sock_fd = Socket(AF_INET, SOCK_SEQPACKET, IPPROTO_SCTP);
16 bzero(&servaddr, sizeof(servaddr));
17 servaddr.sin_family = AF_INET;
18 servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
19 servaddr.sin_port = htons(SERV_PORT);
20 Inet_pton(AF_INET, argv[1], &servaddr.sin_addr);
21 bzero(&evnts, sizeof(evnts));
22 evnts.sctp_data_io_event = 1;
23 Setsockopt(sock_fd, IPPROTO_SCTP, SCTP_EVENTS, &evnts, sizeof(evnts));
24 if (echo_to_all == 0)
25 sctpstr_cli(stdin, sock_fd, (SA*)&servaddr, sizeof(servaddr));
26 else
27 sctpstr_cli_echoall(stdin, sock_fd, (SA*)&servaddr,
28 sizeof(servaddr));
29 Close(sock_fd);
30 return(0);
31 }
Проверка аргументов и создание сокета
9-15
Клиент проверяет переданные ему при запуске аргументы командной строки. Сначала проверяется, указан ли в строке IP-адрес узла, на который нужно отправлять сообщения. Затем проверяется, указан ли параметр отправки эхо-сообщений всем (мы воспользуемся им в разделе 10.5). Наконец, клиент создает сокет SCTP типа «один-ко-многим». Подготовка адреса сервера
16-20
Клиент преобразует IP-адрес сервера, переданный ему в командной строке, с помощью функции inet_pton
. К адресу он добавляет заранее известный номер порта сервера. Полученная структура используется для всех обращений к данному серверу. Подписка на уведомления
21-23
Клиент явно указывает, какие именно уведомления он хочет получать от созданного сокета SCTP. События MSG_NOTIFICATION
ему не нужны, поэтому он отключает их, оставляя лишь структуру sctp_sndrcvinfo
. Вызов функции обработки сообщений
24-28
Если флаг echo_to_all
не установлен, клиент вызывает функцию sctpstr_cli
, которая будет обсуждаться в разделе 10.4. В противном случае вызывается sctpstr_cli_echoall
(раздел 10.5, где рассматривается применение потоков SCTP). Завершение работы
29-31
Закончив работу с сообщениями, клиент закрывает сокет SCTP, что приводит к закрытию всех ассоциаций, использующих этот сокет. Затем функция main
завершается и возвращает код 0 — никаких ошибок не произошло.