UNIX: разработка сетевых приложений - Уильям Стивенс
0/0

UNIX: разработка сетевых приложений - Уильям Стивенс

Уважаемые читатели!
Тут можно читать бесплатно UNIX: разработка сетевых приложений - Уильям Стивенс. Жанр: Программное обеспечение. Так же Вы можете читать полную версию (весь текст) онлайн книги без регистрации и SMS на сайте Knigi-online.info (книги онлайн) или прочесть краткое содержание, описание, предисловие (аннотацию) от автора и ознакомиться с отзывами (комментариями) о произведении.
Описание онлайн-книги UNIX: разработка сетевых приложений - Уильям Стивенс:
Новое издание книги, посвященной созданию веб-серверов, клиент-серверных приложений или любого другого сетевого программного обеспечения в операционной системе UNIX, — классическое руководство по сетевым программным интерфейсам, в частности сокетам. Оно основано на трудах Уильяма Стивенса и полностью переработано и обновлено двумя ведущими экспертами по сетевому программированию. В книгу включено описание ключевых современных стандартов, реализаций и методов, она содержит большое количество иллюстрирующих примеров и может использоваться как учебник по программированию в сетях, так и в качестве справочника для опытных программистов.

Аудиокнига "UNIX: разработка сетевых приложений" от Уильяма Стивенса



📚 "UNIX: разработка сетевых приложений" - это увлекательное путешествие в мир UNIX и сетевого программирования. В книге автор подробно рассматривает основные принципы разработки сетевых приложений под UNIX, раскрывая множество интересных тем и примеров.



Главный герой книги - опытный разработчик, который стремится углубить свои знания в области сетевого программирования под UNIX. Он исследует различные аспекты работы с сетью, изучает протоколы передачи данных и на практике применяет полученные знания.



👨‍💻 Уильям Стивенс - известный специалист в области компьютерных наук, автор множества книг по сетевому программированию. Его работы пользуются популярностью среди разработчиков и студентов по всему миру.



На сайте knigi-online.info вы можете бесплатно и без регистрации слушать аудиокниги онлайн на русском языке. Здесь собраны бестселлеры и лучшие произведения различных жанров, чтобы каждый мог найти что-то по душе.



🎧 Погрузитесь в увлекательный мир UNIX и сетевого программирования вместе с аудиокнигой "UNIX: разработка сетевых приложений" от Уильяма Стивенса. Развивайте свои навыки, открывайте новые горизонты и наслаждайтесь процессом обучения!

Читем онлайн UNIX: разработка сетевых приложений - Уильям Стивенс

Шрифт:

-
+

Интервал:

-
+

Закладка:

Сделать
1 ... 172 173 174 175 176 177 178 179 180 ... 263

Листинг 23.1. Включение автоматического закрытия сокета на сервере

//sctp/sctpserv04.c

14 if (argc == 2)

15  stream_increment = atoi(argv[1]);

16 sock_fd = Socket(AF_INET, SOCK_SEQPACKET, IPPROTO_SCTP);

17 close_time = 120;

18 Setsockopt(sock_fd, IPPROTO_SCTP, SCTP_AUTOCLOSE,

19  &close_time, sizeof(close_time));

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

21 servaddr.sin_family = AF_INET;

22 servaddr.sin_addr.s_addr = htonl(INADDR_ANY);

23 servaddr.sin_report = htons(SERV_PORT);

Установка автоматического закрытия

17-19 Сервер устанавливает ограничение на простой ассоциаций равным 120 с и помещает это значение в переменную close_time. Затем сервер вызывает функцию setsockopt с параметром SCTP_AUTOCLOSE, устанавливающим выбранное ограничение. В остальном код сервера остается прежним.

Теперь SCTP будет автоматически закрывать ассоциации, простаивающие более двух минут. Автоматическое закрытие ассоциаций уменьшает расходы ресурсов сервера на неактивных клиентов.

23.3. Частичная доставка

Механизм частичной доставки (partial delivery) используется стеком SCTP каждый раз, когда требуется доставить приложению большое сообщение. Сообщение считается «большим», если SCTP решает, что у него недостаточно ресурсов на его обработку. Частичная доставка накладывает на работу SCTP определенные ограничения:

■ объем памяти, занимаемой сообщением в буфере, должен превосходить некоторое пороговое значение;

■ доставка может выполняться только последовательно от начала сообщения до первого отсутствующего блока;

■ после включения механизма частичной доставки приложение не может получить никакие другие сообщения до тех пор, пока «большое» сообщение не будет им полностью считано из буфера. Таким образом, большое сообщение блокирует все остальные, которые в противном случае могли бы быть доставлены (в том числе и по другим потокам).

В реализации SCTP, выполненной группой KAME, используется пороговое значение, равное половине объема приемного буфера сокета. На момент написания этой книги объем приемного буфера по умолчанию составляет 131 072 байта. Если параметр сокета SO_RCVBUF не меняется, механизм частичной доставки будет включаться только для сообщений, превышающих 65 536 байт. Мы продолжим расширение новой версии сервера из раздела 10.2, написав функцию-обертку для вызова sctp_recvmsg. Затем мы создадим новый сервер, который будет использовать эту функцию. В листинге 23.2 представлена функция-обертка, способная работать с механизмом частичной доставки.

Листинг 23.2. Работа с API частичной доставки

//sctp/sctp_pdapirev.c

 1 #include "unp.h"

 2 static uint8_t *sctp_pdapi_readbuf=NULL;

 3 static int sctp_pdapi_rdbuf_sz=0;

 4 uint8_t*

 5 pdapi_recvmsg(int sock_fd,

 6  int *rdlen,

 7  SA *from,

 8  int *from_len, struct sctp_sndrcvinfo *sri, int *msg_flags)

 9 {

10  int rdsz, left, at_in_buf;

11  int frmlen=0;

12  if (sctp_pdapi_readbuf == NULL) {

13   sctp_pdapi_readbuf = (uint8_t*)Malloc(SCTP_PDAPI_INCR_SZ);

14   sctp_pdapi_rdbuf_sz = SCTP_PDAPI_INCR_SZ;

15  }

16  at_in_buf = Sctp_recvmsg(sock_fd, sctp_pdapi_readbuf, sctp_pdapi_rdbuf_sz,

17   from, from_len,

18   sri.msg_flags);

19  if (at_in_buf < 1) {

20   *rdlen = at_in_buf;

21   return(NULL);

22  }

23  while ((*msg_flags & MSG_EOR) == 0) {

24   left = sctp_pdapi_rdbuf_sz = at_in_buf;

25   if (left < SCTP_PDAPI_NEED_MORE_THRESHOLD) {

26    sctp_pdapi_readbuf =

27     realloc(sctp_pdapi_readbuf,

28      setp_pdapi_rdbuf_sz + SCTP_PDAPI_INCR_SZ);

29    if (sctp_pdapi_readbuf == NULL) {

30     err_quit("sctp_pdapi ran out of memory");

31    }

32    sctp_pdapi_rdbuf_sz += SCTP_PDAPI_INCR_SZ;

33     left = sctp_pdapi_rdbuf_sz - at_in_buf;

34   

35   rdsz = Sctp_recvmsg(sock_fd, &sctp_pdapi_readbuf[at_in_buf],

36    left, NULL, &frmlen, NULL, msg_flags);

37   at_in_buf += rdsz;

38  }

39  *rdlen = at_in_buf;

40  return(sctp_pdapi_readbuf);

41 }

Подготовка статического буфера

12-15 Если статический буфер не выделен, функция выделяет его и инициализирует переменную, хранящую информацию о состоянии этого буфера.

Чтение сообщения

16-18 Первое сообщение считывается из сокета вызовом sctp_recvmsg.

Обработка ошибки чтения

19-22 Если sctp_recvmsg возвращает ошибку или признак конца файла EOF, соответствующий код возвращается вызвавшему нашу функцию процессу без всяких изменений.

Если сообщение считано не полностью

23-24 Если флаги сообщения показывают, что оно было считано не полностью, мы вызываем функцию sctp_recvmsg снова. Предварительно мы вычисляем объем свободного места в буфере.

Проверка необходимости увеличения статического буфера

25-34 Если остаток приемного буфера оказался меньше некоторого минимального значения, этот буфер необходимо увеличить. С этой целью мы вызываем функцию realloc, выделяющую буфер большего размера, после чего копируем в новый буфер данные из старого буфера. Если по какой-то причине размер буфера не может быть увеличен, функция завершает свою работу с выводом сообщения об ошибке.

Получение данных

35-36 Новые данные считываются из буфера вызовом sctp_recvmsg.

Шаг вперед

37-38 Функция увеличивает индекс буфера, после чего возвращается на проверку полного считывания сообщения.

После завершения цикла

39-40 После завершения цикла функция копирует количество считанных байтов в буфер, указатель на который передается ей вызвавшим процессом, и возвращает этому процессу указатель на собственный буфер.

Теперь мы можем изменить сервер 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) */

38   printf("SCTP_ASSOC_CHANGE %s, assoc=0x%xn", str,

39    (uint32_t)sac->sac_assoc_id);

40   break;

41  case SCTP_PEER_ADDR_CHANGE:

42   spc = &snp->sn_paddr_change;

43   switch (spc->spc_state) {

1 ... 172 173 174 175 176 177 178 179 180 ... 263
На этой странице вы можете бесплатно читать книгу UNIX: разработка сетевых приложений - Уильям Стивенс бесплатно.
Похожие на UNIX: разработка сетевых приложений - Уильям Стивенс книги

Оставить комментарий

Рейтинговые книги