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);}Если приходит ответ, но его порядковый номер отличается от предполагаемого, мы снова вызываем функцию
recvfromrecvfromМы вызываем функции
sigsetjmpsiglongjmpSIGALRMdg_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_t14 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-5unprtt.hrtt_info6-10writevhdrwritevsendtoiovecsendmsgrecvmsgsendtorecvfrommsghdrmsg_controlmsg_accright#ifdefmsghdrstatic
