UNIX: разработка сетевых приложений
UNIX: разработка сетевых приложений читать книгу онлайн
Новое издание книги, посвященной созданию веб-серверов, клиент-серверных приложений или любого другого сетевого программного обеспечения в операционной системе UNIX, — классическое руководство по сетевым программным интерфейсам, в частности сокетам. Оно основано на трудах Уильяма Стивенса и полностью переработано и обновлено двумя ведущими экспертами по сетевому программированию. В книгу включено описание ключевых современных стандартов, реализаций и методов, она содержит большое количество иллюстрирующих примеров и может использоваться как учебник по программированию в сетях, так и в качестве справочника для опытных программистов.
Внимание! Книга может содержать контент только для совершеннолетних. Для несовершеннолетних чтение данного контента СТРОГО ЗАПРЕЩЕНО! Если в книге присутствует наличие пропаганды ЛГБТ и другого, запрещенного контента - просьба написать на почту [email protected] для удаления материала
<i> формирование запроса</i>
signal(SIGALRM, sig_alrm); /* устанавливаем обработчик сигнала */
rtt_newpack(); /* инициализируем значение счетчика rexmt нулем */
sendagain:
sendto();
alarm(rtt_start()); /* задаем аргумент функции alarm равным RTO */
if (sigsetjmp(jmpbuf, 1) != 0) {
if (rtt_timeout()) /* удваиваем RTO, обновляем оценочные значения */
<i> отказываемся от дальнейших попыток</i>
goto sendagain; /* повторная передача */
}
do {
recvfrom();
} while (неправильный порядковый номер);
alarm(0); /* отключаем сигнал alarm */
rtt_stop(); /* вычисляем RTT и обновляем оценочные значения */
<i> обрабатываем ответ</i>
}
void sig_alrm(int signo) {
siglongjmp(jmpbuf, 1);
}
Если приходит ответ, но его порядковый номер отличается от предполагаемого, мы снова вызываем функцию
recvfrom
recvfrom
Мы вызываем функции
sigsetjmp
siglongjmp
SIGALRM
dg_send_recv
Листинг 22.6. Функция dg_send_recv: первая половина
//rtt/dg_send_recv.c
1 #include "unprtt.h"
2 #include <setjmp.h>
3 #define RTT_DEBUG
4 static struct rtt_info rttinfo;
5 static int rttinit = 0;
6 static struct msghdr msgsend, msgrecv;
/* предполагается, что обе структуры инициализированы нулем */
7 static struct hdr {
8 uint32_t seq; /* порядковый номер */
9 uint32_t ts; /* отметка времени при отправке */
10 } sendhdr, recvhdr;
11 static void signalrm(int signo);
12 static sigjmp_buf jmpbuf;
13 ssize_t
14 dg_send_recv(int fd, const void *outbuff, size_t outbytes,
15 void *inbuff, size_t inbytes,
16 const SA *destaddr, socklen_t destlen)
17 {
18 ssize_t n;
19 struct iovec iovsend[2], iovrecv[2];
20 if (rttinit == 0) {
21 rtt_init(&rttinfo); /* первый вызов */
22 rttinit = 1;
23 rtt_d_flag = 1;
24 }
25 sendhdr.seq++;
26 msgsend.msg_name = destaddr;
27 msgsend.msg_namelen = destlen;
28 msgsend.msg_iov = iovsend;
29 msgsend.msg_iovlen = 2;
30 iovsend[0].iov_base = &sendhdr;
31 iovsend[0].iov_len = sizeof(struct hdr);
32 iovsend[1].iov_base = outbuff;
33 iovsend[1].iov_len = outbytes;
34 msgrecv.msg_name = NULL;
35 msgrecv.msg_namelen = 0;
36 msgrecv.msg_iov = iovrecv;
37 msgrecv.msg_iovlen = 2;
38 iovrecv[0].iov_base = &recvhdr;
39 iovrecv[0].iov_len = sizeof(struct hdr);
40 iovrecv[l].iov_base = inbuff;
41 iovrecv[l].iov_len = inbytes;
1-5
unprtt.h
rtt_info
6-10
writev
hdr
writev
sendto
iovec
sendmsg
recvmsg
sendto
recvfrom
msghdr
msg_control
msg_accright
#ifdef
msghdr
static