Теперь мы можем изменить сервер SCTP таким образом, чтобы он использовал нашу новую функцию. Новый код представлен в листинге 23.3.
Листинг 23.3. Сервер SCTP, использующий API частичной доставки
//sctp/sctpserv05.c
26 for (;;) {
27 len = sizeof(struct sockaddr_in);
28 bzero(&sri,.sizeof(sri));
29 readbuf = pdapi_recvmsg(sock_fd, &rd_sz,
30 (SA*)&cliaddr, &len, &sri, &msg_flags);
31 if (readbuf == NULL)
32 continue;
Чтение
сообщения
29-30
Сервер вызывает новую функцию-обертку интерфейса частичной доставки. Предварительно обнуляется переменная
sri
.
Проверка наличия считанных данных
31-32
Обратите внимание, что теперь серверу приходится проверять объем буфера, чтобы убедиться, что чтение было успешным. Если буфер оказывается нулевым, программа переходит на начало цикла.
23.4. Уведомления
В разделе 9.14 уже отмечалось, что приложение может подписаться на уведомления, общее количество которых составляет 7 штук. Пока что наше приложение игнорировало все события, за исключением прихода новых данных. В этом разделе приводятся примеры приема и интерпретации уведомлений SCTP о других событиях транспортного уровня. В листинге 23.4 представлена функция, отображающая все получаемые уведомления. Нам придется изменить и код сервера, чтобы разрешить доставку уведомлений обо всех происходящих событиях. Однако сервер не будет использовать получаемые уведомления для чего-либо конкретного.
Листинг 23.4. Функция вывода уведомлений
1 #include "unp.h"
2 void
3 print_notification(char *notify_buf)
4 {
5 union sctp_notification *snp;
6 struct sctp_assoc_change *sac;
7 struct sctp_paddr_change *spc;
8 struct sctp_remote_error *sre;
9 struct sctp_send_failed *ssf;
10 struct sctp_shutdown_event *sse;
11 struct sctp_adaption_event *ae;
12 struct sctp_pdapi_event *pdapi,
13 const char *str;
14 snp = (union sctp_notification*)notify_buf;
15 switch (snp->sn_header.sn_type) {
16 case SCTP_ASSOC_CHANGE:
17 sac = &snp->sn_assoc_change;
18 switch (sac->sac_state) {
19 case SCTP_COMM_UP:
20 str = "COMMUNICATION UP";
21 break;
22 case SCTP_COMM_LOST:
23 str = "COMMUNICATION LOST";
24 break;
25 case SCTP_RESTART:
26 str = "RESTART";
27 break;
28 case SCTP_SHUTDOWN_COMP:
29 str = "SHUTDOWN COMPLETE";
30 break;
31 case SCTP_CANT_STR_ASSOC:
32 str = "CAN'T START ASSOC";
33 break;
34 default:
35 str = "UNKNOWN";
36 break;
37 } /*
конец ветвления switch (sac->sac_state) */