UNIX: разработка сетевых приложений
UNIX: разработка сетевых приложений читать книгу онлайн
Новое издание книги, посвященной созданию веб-серверов, клиент-серверных приложений или любого другого сетевого программного обеспечения в операционной системе UNIX, — классическое руководство по сетевым программным интерфейсам, в частности сокетам. Оно основано на трудах Уильяма Стивенса и полностью переработано и обновлено двумя ведущими экспертами по сетевому программированию. В книгу включено описание ключевых современных стандартов, реализаций и методов, она содержит большое количество иллюстрирующих примеров и может использоваться как учебник по программированию в сетях, так и в качестве справочника для опытных программистов.
Внимание! Книга может содержать контент только для совершеннолетних. Для несовершеннолетних чтение данного контента СТРОГО ЗАПРЕЩЕНО! Если в книге присутствует наличие пропаганды ЛГБТ и другого, запрещенного контента - просьба написать на почту [email protected] для удаления материала
23.3. Частичная доставка
Механизм частичной доставки (partial delivery) используется стеком SCTP каждый раз, когда требуется доставить приложению большое сообщение. Сообщение считается «большим», если SCTP решает, что у него недостаточно ресурсов на его обработку. Частичная доставка накладывает на работу SCTP определенные ограничения:
■ объем памяти, занимаемой сообщением в буфере, должен превосходить некоторое пороговое значение;
■ доставка может выполняться только последовательно от начала сообщения до первого отсутствующего блока;
■ после включения механизма частичной доставки приложение не может получить никакие другие сообщения до тех пор, пока «большое» сообщение не будет им полностью считано из буфера. Таким образом, большое сообщение блокирует все остальные, которые в противном случае могли бы быть доставлены (в том числе и по другим потокам).
В реализации SCTP, выполненной группой KAME, используется пороговое значение, равное половине объема приемного буфера сокета. На момент написания этой книги объем приемного буфера по умолчанию составляет 131 072 байта. Если параметр сокета
SO_RCVBUF
sctp_recvmsg
Листинг 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
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));