UNIX: разработка сетевых приложений
UNIX: разработка сетевых приложений читать книгу онлайн
Новое издание книги, посвященной созданию веб-серверов, клиент-серверных приложений или любого другого сетевого программного обеспечения в операционной системе UNIX, — классическое руководство по сетевым программным интерфейсам, в частности сокетам. Оно основано на трудах Уильяма Стивенса и полностью переработано и обновлено двумя ведущими экспертами по сетевому программированию. В книгу включено описание ключевых современных стандартов, реализаций и методов, она содержит большое количество иллюстрирующих примеров и может использоваться как учебник по программированию в сетях, так и в качестве справочника для опытных программистов.
Внимание! Книга может содержать контент только для совершеннолетних. Для несовершеннолетних чтение данного контента СТРОГО ЗАПРЕЩЕНО! Если в книге присутствует наличие пропаганды ЛГБТ и другого, запрещенного контента - просьба написать на почту [email protected] для удаления материала
Когда мы после внесения этих изменений наберем первую строку ввода, эта строка будет отправлена как широковещательное сообщение, а мы установим аргумент функции
alarmrecvfromrecvfromalarmSIGALRMsleeprecvfromrecvfromrecvfromforТеперь мы проанализируем четыре различных варианта решения этой проблемы: одно некорректное и три различных корректных решения.
Наше первое (некорректное) решение снижает вероятность появления ошибки, блокируя сигнал и предотвращая его доставку, пока наша программа выполняет оставшуюся часть цикла
forЛистинг 20.2. Блокирование сигналов при выполнении в цикле for (некорректное решение)
//bcast/dgclibcast3.c 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 sigset_t sigset_alrm;10 socklen_t len;11 struct sockaddr *preply_addr;12 preply_addr = Malloc(servlen);13 Setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on));14 Sigemptyset(&sigset_alrm);15 Sigaddset(&sigset_alrm, SIGALRM);16 Signal(SIGALRM, recvfrom_alarm);17 while (Fgets(sendline, MAXLINE, fp) != NULL) {18 Sendto(sockfd, sendline, strlen(sendline), 0, pservaddr, servlen);19 alarm(5);20 for (;;) {21 len = servlen;22 Sigprocmask(SIG_UNBLOCK, &sigset_alrm, NULL);23 n = recvfrom(sockfd, recvline, MAXLINE, 0, preply_addr, &len);24 Sigprocmask(SIG_BLOCK, &sigset_alrm, NULL);25 if (n < 0) {26 if (errno == EINTR)27 break; /* окончание ожидания ответа */28 else29 err_sys("recvfrom error");30 } else {31 recvline[n] = 0; /* завершающий нуль */32 printf("from %s: %s",33 Sock_ntop_host(preply_addr, len), recvline);34 }35 }36 }37 free(preply_addr);38 }39 static void40 recvfrom_alarm(int signo)41 {42 return; /* выход из recvfrom() */43 }14-15sigemptysetSIGALRMsigaddset21-24recvfromrecvfromЕсли мы откомпилируем и запустим эту программу, нам будет казаться, что она работает нормально, но все программы, порождающие ситуацию гонок, большую часть времени работают без каких-либо проблем! Проблема остается: разблокирование сигнала, вызов функции
recvfromrecvfromrecvfromrecvfromВариантом решения может быть установка глобального флага при доставке сигнала его обработчиком:
