UNIX: разработка сетевых приложений
UNIX: разработка сетевых приложений читать книгу онлайн
Новое издание книги, посвященной созданию веб-серверов, клиент-серверных приложений или любого другого сетевого программного обеспечения в операционной системе UNIX, — классическое руководство по сетевым программным интерфейсам, в частности сокетам. Оно основано на трудах Уильяма Стивенса и полностью переработано и обновлено двумя ведущими экспертами по сетевому программированию. В книгу включено описание ключевых современных стандартов, реализаций и методов, она содержит большое количество иллюстрирующих примеров и может использоваться как учебник по программированию в сетях, так и в качестве справочника для опытных программистов.
Внимание! Книга может содержать контент только для совершеннолетних. Для несовершеннолетних чтение данного контента СТРОГО ЗАПРЕЩЕНО! Если в книге присутствует наличие пропаганды ЛГБТ и другого, запрещенного контента - просьба написать на почту [email protected] для удаления материала
recvfrom_alarm(int signo) { had_alarm = 1; return;}Флаг сбрасывается в 0 каждый раз, когда вызывается функция
alarmdg_clirecvfromfor (;;) { len = servlen; Sigprocmask(SIG_UNBLOCK, &sigset_alrm, NULL); if (had_alarm == 1) break; n = recvfrom(sockfd, recvline, MAXLINE, 0, preply_addr, &len);Если сигнал был сгенерирован во время его блокирования (после предыдущего возвращения из функции
recvfromsigprocmaskrecvfromrecvfromБлокирование и разблокирование сигнала с помощью функции pselect
Одним из корректных решений будет использование функции
pselectЛистинг 20.3. Блокирование и разблокирование сигналов с помощью функции pselect
//bcast/dgclibcast4.с 1 #include "unp.h" 2 static void recvfrom_alarm(int); 3 void 4 dg_cli(FILE *fp, int sockfd, const SA *pservaddr, socklen_t servlen) 5 { 6 int n; 7 const int on = 1; 8 char sendline[MAXLINE], recvline[MAXLINE + 1]; 9 fd_set rset;10 sigset_t sigset_alrm, sigset_empty;11 socklen_t len;12 struct sockaddr *preply_addr;13 preply_addr = Malloc(servlen);14 Setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on));15 FD_ZERO(&rset);16 Sigemptyset(&sigset_empty);17 Sigemptyset(&sigset_alrm);18 Sigaddset(&sigset_alrm, SIGALRM);19 Signal(SIGALRM, recvfrom_alarm);20 while (Fgets(sendline, MAXLINE, fp) != NULL) {21 Sendto(sockfd, sendline, strlen(sendline), 0, pservaddr, servlen);22 Sigprocmask(SIG_BLOCK, &sigset_alrm, NULL);23 alarm(5);24 for (;;) {25 FD_SET(sockfd, &rset);26 n = pselect(sockfd + 1, &rset, NULL, NULL, NULL, &sigset_empty);27 if (n < 0) {28 if (errno == EINTR)29 break;30 else31 err_sys("pselect error");32 } else if (n != 1)33 err_sys("pselect error; returned %d", n);34 len = servlen;35 n = Recvfrom(sockfd, recvline, MAXLINE, 0, preply_addr, &len);36 recvline[n] = 0; /* завершающий нуль */37 printf("from %s: %s",38 Sock_ntop_host(preply_addr, len), recvline);39 }40 }41 free(preply_addr);42 }43 static void44 recvfrom_alarm(int signo)45 {46 return; /* просто прерываем recvfrom() */47 }22-23SIGALRMpselectsigset_emptypselectSIGALRMpselectpselect34-38recvfromКак мы упоминали в разделе 6.9, функция
pselect
